Advertisement
Guest User

permy

a guest
Nov 21st, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.80 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define FOR(i,a,n) for (LL i = (a), i##__ = (n); i <= i##__; ++i)
  5. #define REP(i,n) FOR(i,0,(n)-1)
  6. #define FORD(i,a,n) for (LL i = (a), i##__ = (n); i >= i##__; --i)
  7. #define REPD(i,n) FORD(i,(n)-1,0)
  8. #define ALL(x) x.begin(), x.end()
  9. #define ALLR(x) x.rbegin(), x.rend()
  10. #define EB emplace_back
  11. #define ST first
  12. #define ND second
  13. #define OS ostream
  14. #define OO(A) template<class... T> OS& operator<<(OS& os, const A<T...>& x) { return __o(os, ALL(x)); }
  15. #define OD(...) OS& operator<<(OS &os, const __VA_ARGS__ &x)
  16. #define SZ(x) ((int)x.size())
  17. #define RS resize
  18. #define V vector
  19. #define nl '\n'
  20.  
  21. typedef long long LL;
  22. typedef pair<int, int> PII;
  23. typedef V<int> VI;
  24. typedef V<VI> VVI;
  25. typedef V<PII> VPII;
  26. typedef V<VPII> VVPII;
  27. typedef V<bool> VB;
  28. typedef V<VB> VVB;
  29.  
  30. template<class I> OS& __o(OS&, I, I);
  31. template<class T, size_t N> OD(array<T, N>) { return __o(os, ALL(x)); }
  32. OO(vector) OO(deque) OO(set) OO(multiset) OO(map) OO(multimap)
  33. template<class A, class B> OD(pair<A, B>) {
  34.     return os << "(" << x.ST << ", " << x.ND << ")";
  35. }
  36. template<class I> OS& __o(OS& os, I a, I b) {
  37.     os << "{ ";
  38.     for (; a != b;)
  39.         os << *a++, os << " ";
  40.     return os << "}";
  41. }
  42. template<class I> OS& __d(OS& os, I a, I b) {
  43.     os << "{\n";
  44.     for (I c = a; a != b; ++a)
  45.         os << "  " << distance(c, a) << ": " << *a << endl;
  46.     return os << "}";
  47. }
  48. template<class... T> void __e(T&&... a) {
  49.     int t[] = {(cerr << forward<T>(a), 0)...}; (void)t;
  50.     cerr << endl;
  51. }
  52.  
  53. template<class A, class B> inline void mini(A& a, B&& b) { if (b < a) a = b; }
  54. template<class A, class B> inline void maxi(A& a, B&& b) { if (b > a) a = b; }
  55.  
  56. inline int pow2(int n) { return sizeof(int) * 8 - __builtin_clz(n); }
  57.  
  58. #ifdef DEBUG
  59. # define D(...) __VA_ARGS__
  60. #else
  61. # define D(...)
  62. #endif
  63.  
  64. #define LOG(x) D(cerr << #x ": " << x << "  ")
  65. #define LOGN(x) D(LOG(x) << endl)
  66. #define DUMP(x) D(cerr << #x ": ", __d(cerr, ALL(x)) << endl)
  67. #define E(...) D(__e(__VA_ARGS__))
  68.  
  69. //end of templates
  70.  
  71. V< V<LL> > dp;
  72. constexpr LL max_k = 1000000000000000001;
  73. LL f(LL n)      /// ZWRACA MAX LICZBE INWERSJI
  74. {
  75.     return (n * (n - 1)) >> 1;
  76. }
  77. LL dp_size(int n)   /// ZWRACA SRODEK
  78. {
  79.     LL x = f(n) + 1;
  80.     if(!(x & 2))
  81.         --x;
  82.     return x >> 1;
  83. }
  84. LL get_dp(int n, LL k)      /// OKRESLA, ILE JEST N-PERMUTACJI O K INWERSJACH
  85. {
  86.     if(f(n) < k)
  87.         return 0;
  88.     LL sz = dp_size(n);
  89.     if(k > sz)
  90.     {
  91.         k = 2 * sz - k;
  92.         if(f(n) % 2)
  93.             ++k;
  94.     }
  95.     if(SZ(dp[n]) <= k)  /// NIE MA TAKIEGO ELTU
  96.         return max_k;
  97.     else
  98.         return dp[n][k];
  99. }
  100.  
  101. struct Tree
  102. {
  103.     int sz;
  104.     VI v;   /// 1 oznacza, ze jeszcze nie bylo danego eltu, 0 ze byl
  105.     Tree(int in)
  106.     {
  107.         in--;
  108.         sz = 2;
  109.         while(in >>= 1)
  110.             sz <<= 1;
  111.         v.RS(sz << 1, 1);
  112.     }
  113.     void ogarnij()
  114.     {
  115.         FORD(i, sz - 1, 1)
  116.             v[i] = v[i << 1] + v[(i << 1) | 1];
  117.         DUMP(v);
  118.     }
  119.     int fajnd(int k)    /// szukanie k-tej jedynki i zmiana jej na 0
  120.     {
  121.         int xd = 1;
  122.         int licznik = 0;
  123.         while((xd <<= 1) < sz)
  124.             if(v[xd] + licznik < k)
  125.                 licznik += v[xd], xd++;
  126.         if(v[xd] + licznik < k)
  127.             licznik += v[xd], xd++;
  128.         int x = xd;
  129.         while(x)
  130.             v[x]--, x >>= 1;
  131.         DUMP(v);
  132.         return xd - sz + 1;
  133.     }
  134. };
  135.  
  136. int main()
  137. {
  138.     ios_base::sync_with_stdio(0);
  139.     cin.tie(0);
  140.  
  141.     LL N, K;
  142.     cin >> N >> K;
  143.  
  144.     if(N % 4 > 1)
  145.         return cout << "NIE", 0;
  146.  
  147.     /// TWORZENIE TABLICY dp
  148.     dp.RS(N + 1);
  149.     dp[0].EB(0);
  150.     FOR(i, 1, N)
  151.         dp[i].EB(1);
  152.     FOR(i, 1, N - 1)
  153.     {
  154.         LL sum = 1;
  155.         FOR(k, 1, dp_size(i + 1))
  156.         {
  157.             sum += get_dp(i, k);
  158.             if(k > i)
  159.                 sum -= get_dp(i, k - i - 1);
  160.             if(sum < max_k)
  161.                 dp[i + 1].EB(sum);
  162.             else
  163.                 break;
  164.         }
  165.     }
  166.     DUMP(dp);
  167.  
  168.     /// LICZENIE
  169.  
  170.     LL inw = f(N) >> 1;
  171.     if(get_dp(N, inw) < K)
  172.         return cout << "NIE" << nl, 0;
  173.     cout << "TAK" << nl;
  174.  
  175.     Tree t(N + 1);
  176.     t.ogarnij();
  177.  
  178.     REPD(i, N)  /// i-ta pozycja od przodu
  179.     {
  180.         if(!inw)
  181.         {
  182.             int v = t.fajnd(1);
  183.             cout << v << " ";
  184.         }
  185.         else
  186.             FOR(act, LL(max(1ll, inw - f(i) + 1)), N)
  187.             {
  188.                 LL nowe = inw - act + 1;
  189.                 if(get_dp(i, nowe) < K)
  190.                     K -= get_dp(i, nowe);
  191.                 else
  192.                 {
  193.                     inw = nowe;
  194.                     int v = t.fajnd(act);
  195.                     cout << v << " ";
  196.                     break;
  197.                 }
  198.             }
  199.     }
  200.     return cout << nl, 0;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement