#include <algorithm> #include <iostream> #include <limits> #include <vector> const long long bigval = std::numeric_limits<long long>::max(); long long addWithoutOverflow(long long lhs, long long rhs) { long long result = (long long)((unsigned long long)lhs + (unsigned long long)rhs); return result < 0 ? bigval : result; } std::vector<std::vector<long long>> mahonian; void initMahonian(int n) { int s = 106; mahonian.resize(n + 1); mahonian.front().resize(s); mahonian.front().front() = 1; for (int i = 0; i < n; i++) { const std::vector<long long>& prev = mahonian[i]; std::vector<long long>& cur = mahonian[i + 1]; cur.resize(s); std::partial_sum(prev.begin(), prev.begin() + s, cur.begin(), addWithoutOverflow); if (i + 1 < s) { for (auto j = cur.rbegin(), k = j + (i + 1); k != cur.rend(); ++j, ++k) { *j -= *k; } } s = std::find(cur.begin(), cur.end(), bigval) - cur.begin(); } } long long getMahonian(long long n, long long p) { long long m = n * (n - 1) >> 1; if (p > m >> 1) p = m - p; if (p < 0) return 0; if (p >= (int)mahonian[n].size()) return bigval; return mahonian[n][p]; } template<class T> class SquareVector { std::vector<std::vector<T>> v; public: SquareVector(int n, int u) { int s = int(std::sqrt(n) + 1); v.resize(s); for (auto&& w : v) { w.resize(std::min(s, n)); n -= w.size(); for (auto&& x : w) { x = ++u; } } } T getAndErase(std::size_t index) { for (auto&& w : v) { if (index < w.size()) { T result = w[index]; w.erase(w.begin() + index); return result; } index -= w.size(); } return 0; } }; int main() { std::ios::sync_with_stdio(false); long long n, k; std::cin >> n >> k; if (n & 2) { std::cout << "NIE\n"; } else { initMahonian(n); long long p = n * (n - 1) >> 2; if (getMahonian(n, p) < k) { std::cout << "NIE\n"; } else { std::cout << "TAK\n"; int u = 0; while (getMahonian(--n, p) >= k) { std::cout << ++u << ' '; } SquareVector<int> v(n + 1, u); for (; n >= 0; n--) { int i = 0; long long m = n * (n - 1) >> 1; if (p > m) { i += p - m; p = m; } long long g; while ((g = getMahonian(n, p)) < k) { k -= g; p--; i++; } std::cout << v.getAndErase(i) << ' '; } std::cout << '\n'; } } 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 110 | #include <algorithm> #include <iostream> #include <limits> #include <vector> const long long bigval = std::numeric_limits<long long>::max(); long long addWithoutOverflow(long long lhs, long long rhs) { long long result = (long long)((unsigned long long)lhs + (unsigned long long)rhs); return result < 0 ? bigval : result; } std::vector<std::vector<long long>> mahonian; void initMahonian(int n) { int s = 106; mahonian.resize(n + 1); mahonian.front().resize(s); mahonian.front().front() = 1; for (int i = 0; i < n; i++) { const std::vector<long long>& prev = mahonian[i]; std::vector<long long>& cur = mahonian[i + 1]; cur.resize(s); std::partial_sum(prev.begin(), prev.begin() + s, cur.begin(), addWithoutOverflow); if (i + 1 < s) { for (auto j = cur.rbegin(), k = j + (i + 1); k != cur.rend(); ++j, ++k) { *j -= *k; } } s = std::find(cur.begin(), cur.end(), bigval) - cur.begin(); } } long long getMahonian(long long n, long long p) { long long m = n * (n - 1) >> 1; if (p > m >> 1) p = m - p; if (p < 0) return 0; if (p >= (int)mahonian[n].size()) return bigval; return mahonian[n][p]; } template<class T> class SquareVector { std::vector<std::vector<T>> v; public: SquareVector(int n, int u) { int s = int(std::sqrt(n) + 1); v.resize(s); for (auto&& w : v) { w.resize(std::min(s, n)); n -= w.size(); for (auto&& x : w) { x = ++u; } } } T getAndErase(std::size_t index) { for (auto&& w : v) { if (index < w.size()) { T result = w[index]; w.erase(w.begin() + index); return result; } index -= w.size(); } return 0; } }; int main() { std::ios::sync_with_stdio(false); long long n, k; std::cin >> n >> k; if (n & 2) { std::cout << "NIE\n"; } else { initMahonian(n); long long p = n * (n - 1) >> 2; if (getMahonian(n, p) < k) { std::cout << "NIE\n"; } else { std::cout << "TAK\n"; int u = 0; while (getMahonian(--n, p) >= k) { std::cout << ++u << ' '; } SquareVector<int> v(n + 1, u); for (; n >= 0; n--) { int i = 0; long long m = n * (n - 1) >> 1; if (p > m) { i += p - m; p = m; } long long g; while ((g = getMahonian(n, p)) < k) { k -= g; p--; i++; } std::cout << v.getAndErase(i) << ' '; } std::cout << '\n'; } } return 0; } |