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