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