#include <cstdio>
#include <iostream>
#include <map>
#define MAX_SIZE (1<<18)
int tab[2*MAX_SIZE];
int wynik[MAX_SIZE];
int n;
long long int k;
int par;
std::map<std::pair<int,int>, int> secik;
int pozycja(int a,int w)
{
if(a>1)
{
if(w*2<=par)
{
for(int i=0;i<a;i++)
{
bool wyk=1;
if(secik.count(std::make_pair(a-1,w))>0)
if(secik[std::make_pair(a-1,w)]<k)
{
k-=secik[std::make_pair(a-1,w)];
w++;
wyk=0;
}
if(wyk)
{
int know=k;
if(pozycja(a-1,w++))
{
wynik[n-a]=i;
return true;
}
secik[std::make_pair(a-1,w-1)]=know-k;
}
}
}
else
return false;
}
else if(w*2==par)
{
k--;
if(k==0)
return true;
}
return false;
}
void dodaj(int a,int s,int k)
{
s+=MAX_SIZE;
k+=MAX_SIZE;
tab[s]+=a;
if(s!=k)
tab[k]+=a;
while(s/2!=k/2)
{
if(s%2==0)
tab[s+1]+=a;
if(k%2==1)
tab[k-1]+=a;
k/=2;
s/=2;
}
}
int wartosc(int a)
{
int w=a;
a+=MAX_SIZE;
while(a)
{
w+=tab[a];
a/=2;
}
return w;
}
int lb(int a)
{
int s=0;
int k=n-1;
while(s<k)
{
int m=s+(k-s)/2;
if(wartosc(m)<a)
s=m+1;
else
k=m;
}
return s;
}
int main()
{
int w;
scanf("%d%llu",&n,&k);
if(n*(n-1)%4)
printf("NIE\n");
else
{
par=n*(n-1)/2;
pozycja(n,0);
if(k)
printf("NIE\n");
else
{
printf("TAK\n");
for(int i=0;i<n;i++)
{
w=lb(wynik[i]);
printf("%d ",w+1);
dodaj(-1,w,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 | #include <cstdio> #include <iostream> #include <map> #define MAX_SIZE (1<<18) int tab[2*MAX_SIZE]; int wynik[MAX_SIZE]; int n; long long int k; int par; std::map<std::pair<int,int>, int> secik; int pozycja(int a,int w) { if(a>1) { if(w*2<=par) { for(int i=0;i<a;i++) { bool wyk=1; if(secik.count(std::make_pair(a-1,w))>0) if(secik[std::make_pair(a-1,w)]<k) { k-=secik[std::make_pair(a-1,w)]; w++; wyk=0; } if(wyk) { int know=k; if(pozycja(a-1,w++)) { wynik[n-a]=i; return true; } secik[std::make_pair(a-1,w-1)]=know-k; } } } else return false; } else if(w*2==par) { k--; if(k==0) return true; } return false; } void dodaj(int a,int s,int k) { s+=MAX_SIZE; k+=MAX_SIZE; tab[s]+=a; if(s!=k) tab[k]+=a; while(s/2!=k/2) { if(s%2==0) tab[s+1]+=a; if(k%2==1) tab[k-1]+=a; k/=2; s/=2; } } int wartosc(int a) { int w=a; a+=MAX_SIZE; while(a) { w+=tab[a]; a/=2; } return w; } int lb(int a) { int s=0; int k=n-1; while(s<k) { int m=s+(k-s)/2; if(wartosc(m)<a) s=m+1; else k=m; } return s; } int main() { int w; scanf("%d%llu",&n,&k); if(n*(n-1)%4) printf("NIE\n"); else { par=n*(n-1)/2; pozycja(n,0); if(k) printf("NIE\n"); else { printf("TAK\n"); for(int i=0;i<n;i++) { w=lb(wynik[i]); printf("%d ",w+1); dodaj(-1,w,n); } } } return 0; } |
English