#include <bits/stdc++.h> #include <ext/pb_ds/detail/standard_policies.hpp> #include <ext/pb_ds/assoc_container.hpp> // Common file #include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update using namespace std; typedef unsigned long long llu; typedef pair<int, int> ii; using namespace __gnu_pbds; typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; const llu INF = 1e18; vector<llu> V[250007]; ordered_set S; inline llu cnt(llu n, llu k) { llu tmp = n * (n - 1LL) >> 1; if(k > tmp) return 0; if(V[n].size() >= k + 1LL) return V[n][k]; if(V[n].size() >= tmp - k + 1LL) return V[n][tmp - k]; return INF + 1LL; } int main() { V[1].push_back(1); for(llu n = 2LL ; n <= 250000LL ; n++) { llu last = n * (n - 1LL) / 2LL / 2LL; V[n].push_back(1LL); for(llu k = 1LL ; k <= last ; k++) { llu tmp = V[n][k - 1]; if(V[n - 1LL].size() < k + 1) { if(k <= (n - 2LL) * (n - 1LL) / 2LL / 2LL) break; if(k <= (n - 2LL) * (n - 1LL) / 2LL) tmp += V[n - 1LL][(n - 2LL) * (n - 1LL) / 2LL - k]; } else tmp += V[n - 1LL][k]; if(k >= n) tmp -= V[n - 1LL][k - n]; if(tmp > INF) break; V[n].push_back(tmp); } } llu n, k; scanf("%llu %llu", &n, &k); llu inv = n * (n - 1) / 2 / 2; if(((n * (n - 1)) % 4LL) || cnt(n, inv) < k) { printf("NIE\n"); return 0; } for(int i = 1 ; i <= n ; i++) S.insert(i); printf("TAK\n"); for( ; n >= 1LL ; n--) { llu first = 1, sum = 0; llu tmp = cnt(n - 1, inv - first + 1); if(tmp == 0) { first = inv + 1 - (n - 1) * (n - 2) / 2LL; tmp = cnt(n - 1, inv - first + 1); } while(sum + tmp < k) { sum += tmp; first++; tmp = cnt(n - 1, inv - first + 1); } printf("%d ", *S.find_by_order(first - 1)); S.erase(S.find_by_order(first - 1)); k -= sum; inv = inv - first + 1; } printf("\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 | #include <bits/stdc++.h> #include <ext/pb_ds/detail/standard_policies.hpp> #include <ext/pb_ds/assoc_container.hpp> // Common file #include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update using namespace std; typedef unsigned long long llu; typedef pair<int, int> ii; using namespace __gnu_pbds; typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; const llu INF = 1e18; vector<llu> V[250007]; ordered_set S; inline llu cnt(llu n, llu k) { llu tmp = n * (n - 1LL) >> 1; if(k > tmp) return 0; if(V[n].size() >= k + 1LL) return V[n][k]; if(V[n].size() >= tmp - k + 1LL) return V[n][tmp - k]; return INF + 1LL; } int main() { V[1].push_back(1); for(llu n = 2LL ; n <= 250000LL ; n++) { llu last = n * (n - 1LL) / 2LL / 2LL; V[n].push_back(1LL); for(llu k = 1LL ; k <= last ; k++) { llu tmp = V[n][k - 1]; if(V[n - 1LL].size() < k + 1) { if(k <= (n - 2LL) * (n - 1LL) / 2LL / 2LL) break; if(k <= (n - 2LL) * (n - 1LL) / 2LL) tmp += V[n - 1LL][(n - 2LL) * (n - 1LL) / 2LL - k]; } else tmp += V[n - 1LL][k]; if(k >= n) tmp -= V[n - 1LL][k - n]; if(tmp > INF) break; V[n].push_back(tmp); } } llu n, k; scanf("%llu %llu", &n, &k); llu inv = n * (n - 1) / 2 / 2; if(((n * (n - 1)) % 4LL) || cnt(n, inv) < k) { printf("NIE\n"); return 0; } for(int i = 1 ; i <= n ; i++) S.insert(i); printf("TAK\n"); for( ; n >= 1LL ; n--) { llu first = 1, sum = 0; llu tmp = cnt(n - 1, inv - first + 1); if(tmp == 0) { first = inv + 1 - (n - 1) * (n - 2) / 2LL; tmp = cnt(n - 1, inv - first + 1); } while(sum + tmp < k) { sum += tmp; first++; tmp = cnt(n - 1, inv - first + 1); } printf("%d ", *S.find_by_order(first - 1)); S.erase(S.find_by_order(first - 1)); k -= sum; inv = inv - first + 1; } printf("\n"); return 0; } |