#include <cstdio> #include <vector> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define FORD(i,a,b) for(int i=(b)-1;i>=(a);--i) #define REP(i,n) FOR(i,0,n) #define REPD(i,n) FORD(i,0,n) #define PB push_back #define SIZE(c) ((int)(c).size()) #define INT(x) int x; scanf("%d", &x) #define LLG(x) LL x; scanf("%lld", &x) typedef long long LL; typedef vector<LL> VLL; typedef vector<VLL> VVLL; const LL m = 1000000000000000000LL; VVLL c; int nr; int avail[1 << 19]; int take(int x) { int i = 1; while (i < nr) { --avail[i]; i <<= 1; if (avail[i] <= x) { x -= avail[i]; ++i; } } --avail[i]; return i - nr; } int main() { INT(n); LLG(k); if (n & 2) { printf("NIE\n"); return 0; } c.resize(n + 1); c[0].PB(1); c[1].PB(1); FOR(i,2,n+1) { int p = min((LL(i) * (i - 1) >> 1) + 1, 1000LL); VLL& c1 = c[i - 1]; VLL& c2 = c[i]; c2.reserve(SIZE(c1)); REP(j,p) { if (j < SIZE(c1) && c1[j] > m) { c2.PB(m + 1); break; } LL x = 0; if (j < SIZE(c1)) x += c1[j]; if (j) x += c2.back(); if (j >= i) x -= c1[j - i]; if (x > m) { c2.PB(m + 1); break; } c2.PB(x); } } LL t = LL(n) * (n - 1) >> 2; nr = 1; while (nr < n) nr <<= 1; int nr2 = nr << 1; int a = nr2; FOR(i,1,nr2) { if (!(i & (i - 1))) a >>= 1; avail[i] = a; } REPD(i,n) { VLL& cc = c[i]; LL s = 0; LL si = LL(i) * (i - 1) >> 1; int r = -1; int start = min(max(t - si, 0LL), LL(i+1)); FOR(x,start,i+1) { LL p = t - x; LL v = 0; if (p < SIZE(cc)) v = cc[p]; else if (si - p < SIZE(cc)) v = cc[si - p]; else v = m + 1; if (s + v >= k) { r = x; break; } s += v; } if (r < 0) { printf("NIE\n"); return 0; } if (i == n - 1) printf("TAK\n"); else printf(" "); int r2 = r, o = 0; printf("%d", take(r) + 1); k -= s; t -= r; } printf("\n"); }
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 | #include <cstdio> #include <vector> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define FORD(i,a,b) for(int i=(b)-1;i>=(a);--i) #define REP(i,n) FOR(i,0,n) #define REPD(i,n) FORD(i,0,n) #define PB push_back #define SIZE(c) ((int)(c).size()) #define INT(x) int x; scanf("%d", &x) #define LLG(x) LL x; scanf("%lld", &x) typedef long long LL; typedef vector<LL> VLL; typedef vector<VLL> VVLL; const LL m = 1000000000000000000LL; VVLL c; int nr; int avail[1 << 19]; int take(int x) { int i = 1; while (i < nr) { --avail[i]; i <<= 1; if (avail[i] <= x) { x -= avail[i]; ++i; } } --avail[i]; return i - nr; } int main() { INT(n); LLG(k); if (n & 2) { printf("NIE\n"); return 0; } c.resize(n + 1); c[0].PB(1); c[1].PB(1); FOR(i,2,n+1) { int p = min((LL(i) * (i - 1) >> 1) + 1, 1000LL); VLL& c1 = c[i - 1]; VLL& c2 = c[i]; c2.reserve(SIZE(c1)); REP(j,p) { if (j < SIZE(c1) && c1[j] > m) { c2.PB(m + 1); break; } LL x = 0; if (j < SIZE(c1)) x += c1[j]; if (j) x += c2.back(); if (j >= i) x -= c1[j - i]; if (x > m) { c2.PB(m + 1); break; } c2.PB(x); } } LL t = LL(n) * (n - 1) >> 2; nr = 1; while (nr < n) nr <<= 1; int nr2 = nr << 1; int a = nr2; FOR(i,1,nr2) { if (!(i & (i - 1))) a >>= 1; avail[i] = a; } REPD(i,n) { VLL& cc = c[i]; LL s = 0; LL si = LL(i) * (i - 1) >> 1; int r = -1; int start = min(max(t - si, 0LL), LL(i+1)); FOR(x,start,i+1) { LL p = t - x; LL v = 0; if (p < SIZE(cc)) v = cc[p]; else if (si - p < SIZE(cc)) v = cc[si - p]; else v = m + 1; if (s + v >= k) { r = x; break; } s += v; } if (r < 0) { printf("NIE\n"); return 0; } if (i == n - 1) printf("TAK\n"); else printf(" "); int r2 = r, o = 0; printf("%d", take(r) + 1); k -= s; t -= r; } printf("\n"); } |