#include <iostream> #include <vector> #include <deque> using namespace std; const long long maxk = 1000000000000000000ll; long long add_bounded(long long x, long long y) { if(x + y > maxk) return maxk + 1; else return x + y; } int main() { long long n, k; cin >> n >> k; vector<vector<long long> > fn; fn.push_back(vector<long long>()); fn.push_back(vector<long long>(1)); fn[1][0] = 1; for(long long ni = 2; ni < n; ni++) { // wypelniamy rzad nr ni vector<long long> row; for(long long ri = 0; ri <= ni*(ni-1)/2; ri++) { long long s = 0; for(long long i = 0; i < ni && ri-i>=0; i++) if(fn.back().size() > ri-i) { s = add_bounded(s, fn.back()[ri-i] ); } row.push_back(s); if(s > maxk) break; } fn.push_back(row); } vector<long> result(n); deque<long> remain; for(long i = 1; i <= n; i++) remain.push_back(i); if(n%4!=0 && n%4!=1) { cout << "NIE\n"; return 0; } long long inv = n*(n-1)/4; for(int pos = 0; pos < n; pos++) { int nr = 0; long long row_nr = n-pos-1; long long offset = inv - row_nr*(row_nr-1)/2; if(offset < 0) offset = 0; if(offset > remain.size()) { cout << "NIE\n"; return 0; } inv -= offset; for(auto it = remain.begin()+offset; ; it++, nr++) { if(it == remain.end()) { cout << "NIE\n"; return 0; } long long col_nr = row_nr*(row_nr-1)/2 - inv; if(col_nr > inv) col_nr = inv; long long mah = 0; if(col_nr >= 0) { mah = maxk+1; if(fn[row_nr].size() > col_nr) mah = fn[row_nr][col_nr]; } if( mah >= k ) { result[pos] = *it; remain.erase(it); break; } else { k -= mah; inv--; } } } if(k == 1) { cout << "TAK" << endl;; for(int i = 0; i < n; i++) cout << result[i] << " "; cout << endl; } else cout << "NIE" << endl; return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #include <iostream> #include <vector> #include <deque> using namespace std; const long long maxk = 1000000000000000000ll; long long add_bounded(long long x, long long y) { if(x + y > maxk) return maxk + 1; else return x + y; } int main() { long long n, k; cin >> n >> k; vector<vector<long long> > fn; fn.push_back(vector<long long>()); fn.push_back(vector<long long>(1)); fn[1][0] = 1; for(long long ni = 2; ni < n; ni++) { // wypelniamy rzad nr ni vector<long long> row; for(long long ri = 0; ri <= ni*(ni-1)/2; ri++) { long long s = 0; for(long long i = 0; i < ni && ri-i>=0; i++) if(fn.back().size() > ri-i) { s = add_bounded(s, fn.back()[ri-i] ); } row.push_back(s); if(s > maxk) break; } fn.push_back(row); } vector<long> result(n); deque<long> remain; for(long i = 1; i <= n; i++) remain.push_back(i); if(n%4!=0 && n%4!=1) { cout << "NIE\n"; return 0; } long long inv = n*(n-1)/4; for(int pos = 0; pos < n; pos++) { int nr = 0; long long row_nr = n-pos-1; long long offset = inv - row_nr*(row_nr-1)/2; if(offset < 0) offset = 0; if(offset > remain.size()) { cout << "NIE\n"; return 0; } inv -= offset; for(auto it = remain.begin()+offset; ; it++, nr++) { if(it == remain.end()) { cout << "NIE\n"; return 0; } long long col_nr = row_nr*(row_nr-1)/2 - inv; if(col_nr > inv) col_nr = inv; long long mah = 0; if(col_nr >= 0) { mah = maxk+1; if(fn[row_nr].size() > col_nr) mah = fn[row_nr][col_nr]; } if( mah >= k ) { result[pos] = *it; remain.erase(it); break; } else { k -= mah; inv--; } } } if(k == 1) { cout << "TAK" << endl;; for(int i = 0; i < n; i++) cout << result[i] << " "; cout << endl; } else cout << "NIE" << endl; return 0; } |