- #include <iostream> 
- #include <numeric> 
- #include <vector> 
- #include <random> 
- #include <algorithm> 
-   
- int pCount(int n, int m, int myMax) { 
-   
-     if (myMax * m < n) return 0; 
-     if (myMax * m == n) return 1; 
-   
-     if (m < 2) return m; 
-     if (n < m) return 0; 
-     if (n <= m + 1) return 1; 
-   
-     int niter = n / m; 
-     int count = 0; 
-   
-     for (; niter--; n -= m, --myMax) { 
-         count += pCount(n - 1, m - 1, myMax); 
-     } 
-   
-     return count; 
- } 
-   
- std::vector<int> unRank(int n, int m, int myMax, int nth) { 
-   
-     std::vector<int> z(m, 0); 
-     int count = 0; 
-     int j = 0; 
-   
-     for (int i = 0; i < z.size(); ++i) { 
-         int temp = pCount(n - 1, m - 1, myMax); 
-   
-         for (int r = n - m, k = myMax - 1; 
-              (count + temp) < nth && r > 0 && k; r -= m, --k) { 
-   
-             count += temp; 
-             n = r; 
-             myMax = k; 
-             ++j; 
-             temp = pCount(n - 1, m - 1, myMax); 
-         } 
-   
-         --m; 
-         --n; 
-         z[i] = j; 
-     } 
-   
-     return z; 
- } 
-   
- int main() { 
- 	int max = 10; 
- 	int min = 3; 
- 	int N = 7; 
- 	int sum = 42; 
-   
-     int m = N; 
-     int n = sum - m * (min - 1); 
-     int myMax = max - min + 1; 
-     int totalNum = pCount(n, m, myMax); 
-   
-     std::vector<int> v(max - min + 1); 
-     std::iota(v.begin(), v.end(), min); 
-   
-     std::vector<int> indexVec(totalNum); 
-     std::random_device rd; 
-     std::mt19937 gen(rd()); 
-     std::iota(indexVec.begin(), indexVec.end(), 1); 
-     std::shuffle(indexVec.begin(), indexVec.end(), gen); 
-   
-     // random-sample without replacement 
-     std::vector<int> randVec(indexVec.begin(), indexVec.begin() + 20); 
-   
-     for (auto index: randVec) { 
- 	    std::vector<int> z = unRank(n, m, myMax, index); 
- 	    std::cout << index << ": "; 
-   
- 	    for (int i = 0; i < m; ++i) 
- 	        std::cout << v[z[i]] << " "; 
-   
- 	    std::cout << "\n"; 
- 	} 
-   
-     std::cout << std::endl; 
-     return 0; 
- } 
				I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCmludCBwQ291bnQoaW50IG4sIGludCBtLCBpbnQgbXlNYXgpIHsKCiAgICBpZiAobXlNYXggKiBtIDwgbikgcmV0dXJuIDA7CiAgICBpZiAobXlNYXggKiBtID09IG4pIHJldHVybiAxOwoKICAgIGlmIChtIDwgMikgcmV0dXJuIG07CiAgICBpZiAobiA8IG0pIHJldHVybiAwOwogICAgaWYgKG4gPD0gbSArIDEpIHJldHVybiAxOwoKICAgIGludCBuaXRlciA9IG4gLyBtOwogICAgaW50IGNvdW50ID0gMDsKCiAgICBmb3IgKDsgbml0ZXItLTsgbiAtPSBtLCAtLW15TWF4KSB7CiAgICAgICAgY291bnQgKz0gcENvdW50KG4gLSAxLCBtIC0gMSwgbXlNYXgpOwogICAgfQoKICAgIHJldHVybiBjb3VudDsKfQoKc3RkOjp2ZWN0b3I8aW50PiB1blJhbmsoaW50IG4sIGludCBtLCBpbnQgbXlNYXgsIGludCBudGgpIHsKCiAgICBzdGQ6OnZlY3RvcjxpbnQ+IHoobSwgMCk7CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IGogPSAwOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgei5zaXplKCk7ICsraSkgewogICAgICAgIGludCB0ZW1wID0gcENvdW50KG4gLSAxLCBtIC0gMSwgbXlNYXgpOwoKICAgICAgICBmb3IgKGludCByID0gbiAtIG0sIGsgPSBteU1heCAtIDE7CiAgICAgICAgICAgICAoY291bnQgKyB0ZW1wKSA8IG50aCAmJiByID4gMCAmJiBrOyByIC09IG0sIC0taykgewoKICAgICAgICAgICAgY291bnQgKz0gdGVtcDsKICAgICAgICAgICAgbiA9IHI7CiAgICAgICAgICAgIG15TWF4ID0gazsKICAgICAgICAgICAgKytqOwogICAgICAgICAgICB0ZW1wID0gcENvdW50KG4gLSAxLCBtIC0gMSwgbXlNYXgpOwogICAgICAgIH0KCiAgICAgICAgLS1tOwogICAgICAgIC0tbjsKICAgICAgICB6W2ldID0gajsKICAgIH0KCiAgICByZXR1cm4gejsKfQoKaW50IG1haW4oKSB7CglpbnQgbWF4ID0gMTA7CglpbnQgbWluID0gMzsKCWludCBOID0gNzsKCWludCBzdW0gPSA0MjsKCQogICAgaW50IG0gPSBOOwogICAgaW50IG4gPSBzdW0gLSBtICogKG1pbiAtIDEpOwogICAgaW50IG15TWF4ID0gbWF4IC0gbWluICsgMTsKICAgIGludCB0b3RhbE51bSA9IHBDb3VudChuLCBtLCBteU1heCk7CiAgICAKICAgIHN0ZDo6dmVjdG9yPGludD4gdihtYXggLSBtaW4gKyAxKTsKICAgIHN0ZDo6aW90YSh2LmJlZ2luKCksIHYuZW5kKCksIG1pbik7CiAgICAKICAgIHN0ZDo6dmVjdG9yPGludD4gaW5kZXhWZWModG90YWxOdW0pOwogICAgc3RkOjpyYW5kb21fZGV2aWNlIHJkOwogICAgc3RkOjptdDE5OTM3IGdlbihyZCgpKTsKICAgIHN0ZDo6aW90YShpbmRleFZlYy5iZWdpbigpLCBpbmRleFZlYy5lbmQoKSwgMSk7CiAgICBzdGQ6OnNodWZmbGUoaW5kZXhWZWMuYmVnaW4oKSwgaW5kZXhWZWMuZW5kKCksIGdlbik7CgogICAgLy8gcmFuZG9tLXNhbXBsZSB3aXRob3V0IHJlcGxhY2VtZW50CiAgICBzdGQ6OnZlY3RvcjxpbnQ+IHJhbmRWZWMoaW5kZXhWZWMuYmVnaW4oKSwgaW5kZXhWZWMuYmVnaW4oKSArIDIwKTsKICAgIAogICAgZm9yIChhdXRvIGluZGV4OiByYW5kVmVjKSB7CgkgICAgc3RkOjp2ZWN0b3I8aW50PiB6ID0gdW5SYW5rKG4sIG0sIG15TWF4LCBpbmRleCk7CgkgICAgc3RkOjpjb3V0IDw8IGluZGV4IDw8ICI6ICI7CiAKCSAgICBmb3IgKGludCBpID0gMDsgaSA8IG07ICsraSkKCSAgICAgICAgc3RkOjpjb3V0IDw8IHZbeltpXV0gPDwgIiAiOwogCgkgICAgc3RkOjpjb3V0IDw8ICJcbiI7Cgl9CgkKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQ==