#include <bits/stdc++.h> using namespace std; const int N = 250005; const int M = 105; #define REP(i, n) for (int i = 0; i < (n); ++i) typedef long long ll; const ll linf = 2e18; ll g[N][25], f[M][M*M]; ll n, k; ll calc(ll n, ll inv) { if (inv < 0 || inv > n*(n-1)/2) return 0; if (n <= 100) return f[n][inv]; inv = min(inv, n*(n-1)/2-inv); if (inv > 20) return linf; return g[n][inv]; } void add(ll &x, ll y) { x += y; if (x >= linf) x = linf; } void precalc() { int n = 102; f[1][0] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j <= (i-1)*(i-2)/2; ++j) { for (int w = 0; w < i; ++w) { add(f[i][j + w], f[i-1][j]); } } } n = 250002; g[1][0] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j <= 20; ++j) { for (int w = 0; w < i && w + j <= 20; ++w) { add(g[i][j + w], g[i-1][j]); } } } } void die() { cout << "NIE\n"; exit(0); } int a[N]; int cnt[4*N]; void build(int v, int tl, int tr) { if (tl == tr) { cnt[v] = 1; return; } int tm = (tl + tr) / 2; build(2*v, tl, tm); build(2*v+1, tm+1, tr); cnt[v] = cnt[2*v] + cnt[2*v+1]; } void update(int v, int tl, int tr, int pos) { if (tl == tr) { cnt[v] = 0; return; } int tm = (tl + tr) / 2; if (pos <= tm) { update(2*v, tl, tm, pos); } else { update(2*v+1, tm+1, tr, pos); } cnt[v] = cnt[2*v] + cnt[2*v+1]; } int go(int v, int tl, int tr, int e) { if (tl == tr) return tl; int tm = (tl + tr) / 2; if (cnt[2*v] >= e) return go(2*v, tl, tm, e); return go(2*v+1, tm+1, tr, e - cnt[2*v]); } int result[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); precalc(); cin >> n >> k; if (n % 4 > 1) die(); ll inv = n*(n-1)/4; if (calc(n, inv) < k) die(); for (int i = 0; i < n - 1; ++i) { ll start = max(0LL, inv - (n-i-1)*(n-i-2)/2); for (ll j = start; j < n - i && inv >= j; ++j) { ll now = inv - j; if (calc(n - i - 1, now) >= k) { a[i] = j; inv = now; break; } k -= calc(n - i - 1, now); } } build(1, 0, n - 1); REP(i, n) { result[i] = go(1, 0, n - 1, a[i] + 1); update(1, 0, n - 1, result[i]); } cout << "TAK\n"; REP(i, n) { cout << result[i]+1 << ' '; } 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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #include <bits/stdc++.h> using namespace std; const int N = 250005; const int M = 105; #define REP(i, n) for (int i = 0; i < (n); ++i) typedef long long ll; const ll linf = 2e18; ll g[N][25], f[M][M*M]; ll n, k; ll calc(ll n, ll inv) { if (inv < 0 || inv > n*(n-1)/2) return 0; if (n <= 100) return f[n][inv]; inv = min(inv, n*(n-1)/2-inv); if (inv > 20) return linf; return g[n][inv]; } void add(ll &x, ll y) { x += y; if (x >= linf) x = linf; } void precalc() { int n = 102; f[1][0] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j <= (i-1)*(i-2)/2; ++j) { for (int w = 0; w < i; ++w) { add(f[i][j + w], f[i-1][j]); } } } n = 250002; g[1][0] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j <= 20; ++j) { for (int w = 0; w < i && w + j <= 20; ++w) { add(g[i][j + w], g[i-1][j]); } } } } void die() { cout << "NIE\n"; exit(0); } int a[N]; int cnt[4*N]; void build(int v, int tl, int tr) { if (tl == tr) { cnt[v] = 1; return; } int tm = (tl + tr) / 2; build(2*v, tl, tm); build(2*v+1, tm+1, tr); cnt[v] = cnt[2*v] + cnt[2*v+1]; } void update(int v, int tl, int tr, int pos) { if (tl == tr) { cnt[v] = 0; return; } int tm = (tl + tr) / 2; if (pos <= tm) { update(2*v, tl, tm, pos); } else { update(2*v+1, tm+1, tr, pos); } cnt[v] = cnt[2*v] + cnt[2*v+1]; } int go(int v, int tl, int tr, int e) { if (tl == tr) return tl; int tm = (tl + tr) / 2; if (cnt[2*v] >= e) return go(2*v, tl, tm, e); return go(2*v+1, tm+1, tr, e - cnt[2*v]); } int result[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); precalc(); cin >> n >> k; if (n % 4 > 1) die(); ll inv = n*(n-1)/4; if (calc(n, inv) < k) die(); for (int i = 0; i < n - 1; ++i) { ll start = max(0LL, inv - (n-i-1)*(n-i-2)/2); for (ll j = start; j < n - i && inv >= j; ++j) { ll now = inv - j; if (calc(n - i - 1, now) >= k) { a[i] = j; inv = now; break; } k -= calc(n - i - 1, now); } } build(1, 0, n - 1); REP(i, n) { result[i] = go(1, 0, n - 1, a[i] + 1); update(1, 0, n - 1, result[i]); } cout << "TAK\n"; REP(i, n) { cout << result[i]+1 << ' '; } cout << '\n'; return 0; } |