#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; } |
English