Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define FOR(i,a,n) for (LL i = (a), i##__ = (n); i <= i##__; ++i)
- #define REP(i,n) FOR(i,0,(n)-1)
- #define FORD(i,a,n) for (LL i = (a), i##__ = (n); i >= i##__; --i)
- #define REPD(i,n) FORD(i,(n)-1,0)
- #define ALL(x) x.begin(), x.end()
- #define ALLR(x) x.rbegin(), x.rend()
- #define EB emplace_back
- #define ST first
- #define ND second
- #define OS ostream
- #define OO(A) template<class... T> OS& operator<<(OS& os, const A<T...>& x) { return __o(os, ALL(x)); }
- #define OD(...) OS& operator<<(OS &os, const __VA_ARGS__ &x)
- #define SZ(x) ((int)x.size())
- #define RS resize
- #define V vector
- #define nl '\n'
- typedef long long LL;
- typedef pair<int, int> PII;
- typedef V<int> VI;
- typedef V<VI> VVI;
- typedef V<PII> VPII;
- typedef V<VPII> VVPII;
- typedef V<bool> VB;
- typedef V<VB> VVB;
- template<class I> OS& __o(OS&, I, I);
- template<class T, size_t N> OD(array<T, N>) { return __o(os, ALL(x)); }
- OO(vector) OO(deque) OO(set) OO(multiset) OO(map) OO(multimap)
- template<class A, class B> OD(pair<A, B>) {
- return os << "(" << x.ST << ", " << x.ND << ")";
- }
- template<class I> OS& __o(OS& os, I a, I b) {
- os << "{ ";
- for (; a != b;)
- os << *a++, os << " ";
- return os << "}";
- }
- template<class I> OS& __d(OS& os, I a, I b) {
- os << "{\n";
- for (I c = a; a != b; ++a)
- os << " " << distance(c, a) << ": " << *a << endl;
- return os << "}";
- }
- template<class... T> void __e(T&&... a) {
- int t[] = {(cerr << forward<T>(a), 0)...}; (void)t;
- cerr << endl;
- }
- template<class A, class B> inline void mini(A& a, B&& b) { if (b < a) a = b; }
- template<class A, class B> inline void maxi(A& a, B&& b) { if (b > a) a = b; }
- inline int pow2(int n) { return sizeof(int) * 8 - __builtin_clz(n); }
- #ifdef DEBUG
- # define D(...) __VA_ARGS__
- #else
- # define D(...)
- #endif
- #define LOG(x) D(cerr << #x ": " << x << " ")
- #define LOGN(x) D(LOG(x) << endl)
- #define DUMP(x) D(cerr << #x ": ", __d(cerr, ALL(x)) << endl)
- #define E(...) D(__e(__VA_ARGS__))
- //end of templates
- V< V<LL> > dp;
- constexpr LL max_k = 1000000000000000001;
- LL f(LL n) /// ZWRACA MAX LICZBE INWERSJI
- {
- return (n * (n - 1)) >> 1;
- }
- LL dp_size(int n) /// ZWRACA SRODEK
- {
- LL x = f(n) + 1;
- if(!(x & 2))
- --x;
- return x >> 1;
- }
- LL get_dp(int n, LL k) /// OKRESLA, ILE JEST N-PERMUTACJI O K INWERSJACH
- {
- if(f(n) < k)
- return 0;
- LL sz = dp_size(n);
- if(k > sz)
- {
- k = 2 * sz - k;
- if(f(n) % 2)
- ++k;
- }
- if(SZ(dp[n]) <= k) /// NIE MA TAKIEGO ELTU
- return max_k;
- else
- return dp[n][k];
- }
- struct Tree
- {
- int sz;
- VI v; /// 1 oznacza, ze jeszcze nie bylo danego eltu, 0 ze byl
- Tree(int in)
- {
- in--;
- sz = 2;
- while(in >>= 1)
- sz <<= 1;
- v.RS(sz << 1, 1);
- }
- void ogarnij()
- {
- FORD(i, sz - 1, 1)
- v[i] = v[i << 1] + v[(i << 1) | 1];
- DUMP(v);
- }
- int fajnd(int k) /// szukanie k-tej jedynki i zmiana jej na 0
- {
- int xd = 1;
- int licznik = 0;
- while((xd <<= 1) < sz)
- if(v[xd] + licznik < k)
- licznik += v[xd], xd++;
- if(v[xd] + licznik < k)
- licznik += v[xd], xd++;
- int x = xd;
- while(x)
- v[x]--, x >>= 1;
- DUMP(v);
- return xd - sz + 1;
- }
- };
- int main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- LL N, K;
- cin >> N >> K;
- if(N % 4 > 1)
- return cout << "NIE", 0;
- /// TWORZENIE TABLICY dp
- dp.RS(N + 1);
- dp[0].EB(0);
- FOR(i, 1, N)
- dp[i].EB(1);
- FOR(i, 1, N - 1)
- {
- LL sum = 1;
- FOR(k, 1, dp_size(i + 1))
- {
- sum += get_dp(i, k);
- if(k > i)
- sum -= get_dp(i, k - i - 1);
- if(sum < max_k)
- dp[i + 1].EB(sum);
- else
- break;
- }
- }
- DUMP(dp);
- /// LICZENIE
- LL inw = f(N) >> 1;
- if(get_dp(N, inw) < K)
- return cout << "NIE" << nl, 0;
- cout << "TAK" << nl;
- Tree t(N + 1);
- t.ogarnij();
- REPD(i, N) /// i-ta pozycja od przodu
- {
- if(!inw)
- {
- int v = t.fajnd(1);
- cout << v << " ";
- }
- else
- FOR(act, LL(max(1ll, inw - f(i) + 1)), N)
- {
- LL nowe = inw - act + 1;
- if(get_dp(i, nowe) < K)
- K -= get_dp(i, nowe);
- else
- {
- inw = nowe;
- int v = t.fajnd(act);
- cout << v << " ";
- break;
- }
- }
- }
- return cout << nl, 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement