Advertisement
Kevin_Zhang

treap

Sep 4th, 2021
1,084
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.78 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. #define pb emplace_back
  5. #define AI(i) begin(i), end(i)
  6. template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true); }
  7. template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true); }
  8. #ifdef KEV
  9. #define DE(args...) kout("[ " + string(#args) + " ] = ", args)
  10. void kout() { cerr << endl; }
  11. template<class T, class ...U> void kout(T a, U ...b) { cerr << a << ' ', kout(b...); }
  12. template<class T> void debug(T l, T r) { while (l != r) cerr << *l << " \n"[next(l)==r], ++l; }
  13. #else
  14. #define DE(...) 0
  15. #define debug(...) 0
  16. #endif
  17.  
  18. const int MAX_N = 1e5 + 100, p = 1e9 + 7;
  19.  
  20. void mul(ll &a, ll b) { a = a * b % p; }
  21.  
  22. int rand() {
  23.     static unsigned x = 1923847;
  24.     return (++x) *= 0xdefaced;
  25. }
  26.  
  27. namespace TP {
  28.     struct node {
  29.         int sz, pa, pri, l, r;
  30.     }room[MAX_N];
  31. #define exp(a) int& a(int i){ return room[i].a; }
  32.  
  33.     exp(sz);
  34.     exp(pa);
  35.     exp(pri);
  36.     exp(l);
  37.     exp(r);
  38.  
  39.     void init(int n) {
  40.         // 0 is null
  41.         for (int i = 1;i < n + 10;++i) {
  42.             pri(i) = rand();
  43.             pa(i) = i;
  44.             sz(i) = 1;
  45.         }
  46.     }
  47.     void upd(int x) {
  48.         if (x == 0) return;
  49.         sz(x) = sz(l(x)) + sz(r(x)) + 1;
  50.         pa(x) = pa(l(x)) = pa(r(x)) = x;
  51.     }
  52.     // cut exactly k stuff
  53.     void split_sz(int x, int k, int &a, int &b) {
  54.         if (x == 0) {
  55.             a = b = 0;
  56.             return;
  57.         }
  58.         if (sz(l(x)) + 1 <= k) {
  59.             a = x;
  60.             split_sz(r(x), k - sz(l(x)) - 1, r(a), b);
  61.         }
  62.         else {
  63.             b = x;
  64.             split_sz(l(x), k, a, l(b));
  65.         }
  66.         upd(a), upd(b);
  67.     }
  68.     void DB(int x) {
  69.         if (x == 0) return;
  70.         DB(l(x));
  71.         cerr << x << ' ';
  72.         DB(r(x));
  73.     }
  74.     int merge(int a, int b) {
  75.         if (!a || !b) return a + b;
  76.         if (pri(a) < pri(b)) {
  77.             r(a) = merge(r(a), b);
  78.             upd(a);
  79.             return a;
  80.         }
  81.         else {
  82.             l(b) = merge(a, l(b));
  83.             upd(b);
  84.             return b;
  85.         }
  86.     }
  87.     // first is rank, second is boss
  88.     // rank is how many stuff is smaller
  89.     pair<int,int> getrb(int x) {
  90.         if (pa(x) == x) return make_pair(0, x);
  91.         auto [rk, bs] = getrb(pa(x));
  92.         if (x == l(pa(x)))
  93.             return make_pair(rk - sz(r(x)) - 1, bs);
  94.         else
  95.             return make_pair(rk + sz(l(x)) + 1, bs);
  96.     }
  97. }
  98.  
  99. int inv[MAX_N];
  100. void init_math() {
  101.     inv[0] = inv[1] = 1;
  102.     for (int i = 2;i < MAX_N;++i)
  103.         inv[i] = (ll)(p - p/i) * inv[p % i] % p;
  104. }
  105. struct get_pfac {
  106.     vector<int> minp, pnum;
  107.     vector<vector<pair<int,int>>> tab;
  108.     vector<pair<int,int>> hp(int v) {
  109.         vector<pair<int,int>> ret;
  110.         while (v > 1) {
  111.             int f = minp[v];
  112.             if (ret.size() && ret.back().first == f) ret.back().second *= f;
  113.             else ret.pb(f, f);
  114.             v /= f;
  115.         }
  116.         return ret;
  117.     }
  118.     get_pfac(int n = 0) {
  119.         n += 10;
  120.         minp.resize(n);
  121.         for (int i = 2;i < n;++i) {
  122.             if (minp[i] == 0) {
  123.                 minp[i] = i;
  124.                 pnum.pb(i);
  125.                 for (int j : pnum) {
  126.                     if ((ll)i * j >= n) break;
  127.                     minp[i * j] = j;
  128.                     if (j % i == 0) break;
  129.                 }
  130.             }
  131.         }
  132.         minp[1] = minp[0] = 1;
  133.         tab.resize(n);
  134.         for (int i = 2;i < n;++i)
  135.             tab[i] = hp(i);
  136.     }
  137.     vector<pair<int,int>> operator ()(int v) { return tab[v]; }
  138. };
  139.  
  140. struct lcms {
  141.     vector<multiset<int>> cnt;
  142.     vector<vector<pair<int,int>>> pfac;
  143.     get_pfac hp;
  144.     ll res = 1;
  145.     lcms(int n) {
  146.         cnt.resize(n + 10);
  147.         pfac.resize(n + 10);
  148.         for (auto &i : cnt)
  149.             i.insert(1);
  150.         hp = get_pfac(n);
  151.     }
  152.     void add(int i, int t) {
  153.         DE(i, t);
  154.         for (auto [f, c] : hp(i)) {
  155.             mul(res, inv[ *cnt[f].rbegin() ]);
  156.             if (t == 1) cnt[f].insert(c);
  157.             else cnt[f].erase(cnt[f].find(c));
  158.             mul(res, *cnt[f].rbegin());
  159.         }
  160.     }
  161. };
  162.  
  163.  
  164. int32_t main() {
  165.     ios_base::sync_with_stdio(0), cin.tie(0);
  166.     init_math();
  167.     int n, q;
  168.     cin >> n >> q;
  169.  
  170.     TP::init(n);
  171.  
  172.     lcms LC(n);
  173.  
  174.     vector<int> nxt(n + 1); iota(AI(nxt), 0);
  175.  
  176.     auto doop = [&](int a, int b) {
  177.         int oa = a, ob = b;
  178.         a = nxt[a], b = nxt[b];
  179.  
  180.         auto [r1, b1] = TP::getrb(a);
  181.         auto [r2, b2] = TP::getrb(b);
  182.  
  183.         DE(oa, ob);
  184.  
  185.         if (b1 == b2) {
  186.             TP::DB(b1);
  187.  
  188.  
  189.             LC.add(TP::sz(b1), -1);
  190.             if (r1 > r2) swap(r1, r2), swap(a, b);
  191.             int A, B, C, D, E;
  192.             TP::split_sz(b1, r2, D, C);
  193.             TP::split_sz(D, r1, A, B);
  194.             TP::merge(A, C);
  195.  
  196.             tie(r1, b1) = TP::getrb(a);
  197.             tie(r2, b2) = TP::getrb(b);
  198.  
  199.             //DE(b1, b2, TP::sz(b1), TP::sz(b2));
  200.             TP::DB(b1), cerr << endl, TP::DB(b2), cerr << endl;
  201.             LC.add(TP::sz(b1), 1);
  202.             LC.add(TP::sz(b2), 1);
  203.         }
  204.         else {
  205.             LC.add(TP::sz(b1), -1);
  206.             LC.add(TP::sz(b2), -1);
  207.  
  208.             int A, B, C, D;
  209.             TP::split_sz(b1, r1, A, B);
  210.  
  211.             TP::split_sz(b2, r2, C, D);
  212.             DE(b);
  213.             cerr << "DEA " << endl;
  214.             TP::DB(D);
  215.  
  216.             DE(A, B, C, D);
  217.  
  218.             A = TP::merge(A, D);
  219.             A = TP::merge(A, C);
  220.             A = TP::merge(A, B);
  221.  
  222.             tie(r1, b1) = TP::getrb(a);
  223.  
  224.             LC.add(TP::sz(b1), 1);
  225.  
  226.             TP::DB(b1);
  227.             cerr << endl;
  228.         }
  229.         swap(nxt[oa], nxt[ob]);
  230.     };
  231.  
  232.     while (q--) {
  233.         int a, b;
  234.         cin >> a >> b;
  235.         doop(a, b);
  236.         DE(a, b);
  237.         debug(AI(nxt));
  238.         cout << LC.res << '\n';
  239.     }
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement