Advertisement
tien_noob

DSU offline (Add - Delete - Query) - DnC

Feb 16th, 2022
666
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.26 KB | None | 0 0
  1. //Make CSP great again
  2. //You're as beautiful as the day I lost you
  3. //New year, best wishes
  4. #include <bits/stdc++.h>
  5. #define TASK "TESTCODE"
  6. #define Log2(x) 31 - __builtin_clz(x)
  7. using namespace std;
  8. const int N = 1e5;
  9. map<pair<int, int>, vector<int> > Map;
  10. int n, q, a[N + 1], t[N + 1], x[N + 1], y[N + 1], lab[N + 1];
  11. bool res[N + 1];
  12. struct SegmentTree
  13. {
  14.     int Tree[4 * N + 1];
  15.     void BuildTree(int v, int TreeL, int TreeR)
  16.     {
  17.         if (TreeL == TreeR)
  18.         {
  19.             if (t[TreeL] == 1)
  20.             {
  21.                 Tree[v] = a[TreeL];
  22.             }
  23.             else
  24.             {
  25.                 Tree[v] = 0;
  26.             }
  27.             return ;
  28.         }
  29.         int mid = (TreeL + TreeR)/2;
  30.         BuildTree(v * 2, TreeL, mid);
  31.         BuildTree(v * 2 + 1, mid + 1, TreeR);
  32.         Tree[v] = max(Tree[2 * v], Tree[2 * v + 1]);
  33.     }
  34.     void update(int v, int TreeL, int TreeR, int pos, int val)
  35.     {
  36.         if (TreeL == TreeR)
  37.         {
  38.             Tree[v] = val;
  39.             return ;
  40.         }
  41.         int mid = (TreeL + TreeR)/2;
  42.         if (pos <= mid)
  43.         {
  44.             update(v * 2, TreeL, mid, pos, val);
  45.         }
  46.         else
  47.         {
  48.             update(v * 2 + 1, mid + 1, TreeR, pos, val);
  49.         }
  50.         Tree[v] = max(Tree[2 * v], Tree[2 * v + 1]);
  51.     }
  52.     int query(int v, int TreeL, int TreeR, int R)
  53.     {
  54.         if (Tree[v] < R)
  55.         {
  56.             return -1;
  57.         }
  58.         if (TreeL == TreeR)
  59.         {
  60.             return TreeL;
  61.         }
  62.         int mid = (TreeL + TreeR)/2;
  63.         int t = query(v * 2, TreeL, mid, R);
  64.         if (t == -1)
  65.         {
  66.             t = query(v * 2 + 1, mid + 1, TreeR, R);
  67.         }
  68.         return t;
  69.     }
  70. } Tree;
  71. void read()
  72. {
  73.     cin >> n >> q;
  74.     memset(lab, -1, sizeof(lab));
  75.     for (int i = 1; i <= q; ++ i)
  76.     {
  77.         a[i] = q + 1;
  78.         cin >> t[i] >> x[i] >> y[i];
  79.         if (x[i] > y[i])
  80.         {
  81.             swap(x[i], y[i]);
  82.         }
  83.         if (t[i] == 1)
  84.         {
  85.             Map[ {x[i], y[i]}].push_back(i);
  86.         }
  87.         else if (t[i] == 2)
  88.         {
  89.             if (!Map[ {x[i], y[i]}].empty())
  90.             {
  91.                 a[Map[ {x[i], y[i]}].back()] = i;
  92.                 Map[ {x[i], y[i]}].pop_back();
  93.             }
  94.         }
  95.     }
  96.     Tree.BuildTree(1, 1, q);
  97. }
  98. stack<tuple<int, int, int, int, int> > Stack;
  99. void Undo(int s)
  100. {
  101.     while(Stack.size() > s)
  102.     {
  103.         int u, v, sz, i, k;
  104.         tie(u, v, sz, i, k) = Stack.top();
  105.         Stack.pop();
  106.         Tree.update(1, 1, q, i, a[i]);
  107.         if (k == 0)
  108.         {
  109.             continue;
  110.         }
  111.         lab[v] = -sz;
  112.         lab[u] += sz;
  113.     }
  114. }
  115. int FindSet(int u)
  116. {
  117.     return lab[u] < 0 ? u : FindSet(lab[u]);
  118. }
  119. void Unite(int i)
  120. {
  121.     int u = FindSet(x[i]);
  122.     int v = FindSet(y[i]);
  123.     Tree.update(1, 1, q, i, 0);
  124.     if (u == v)
  125.     {
  126.         Stack.push(make_tuple(u, v, -lab[v], i, 0));
  127.         return ;
  128.     }
  129.     if (lab[v] < lab[u])
  130.     {
  131.         swap(u, v);
  132.     }
  133.     Stack.push(make_tuple(u, v, -lab[v], i, 1));
  134.     lab[u] += lab[v];
  135.     lab[v] = u;
  136. }
  137. void Dnc(int L, int R)
  138. {
  139.     if (L > R)
  140.     {
  141.         return ;
  142.     }
  143.     int s = Stack.size();
  144.     while (true)
  145.     {
  146.         int i = Tree.query(1, 1, q, R);
  147.         if (i == -1 || i > L)
  148.         {
  149.             break;
  150.         }
  151.         Unite(i);
  152.     }
  153.     if (L == R)
  154.     {
  155.         if (t[L] == 3)
  156.         {
  157.             int u = FindSet(x[L]), v = FindSet(y[L]);
  158.             res[L] = (u == v);
  159.         }
  160.         Undo(s);
  161.         return ;
  162.     }
  163.     int mid = (L + R)/2;
  164.     Dnc(L, mid);
  165.     Dnc(mid + 1, R);
  166.     Undo(s);
  167. }
  168. void solve()
  169. {
  170.     Dnc(1, q);
  171.     for (int i = 1; i <= q; ++ i)
  172.     {
  173.         if (t[i] == 3)
  174.         {
  175.             cout << (res[i] ? "YES" : "NO") << '\n';
  176.         }
  177.     }
  178. }
  179. int main()
  180. {
  181.     ios_base::sync_with_stdio(false);
  182.     cin.tie(nullptr);
  183.     if (fopen(TASK".INP", "r"))
  184.     {
  185.         freopen(TASK".INP", "r", stdin);
  186.         //freopen(TASK".OUT", "w", stdout);
  187.     }
  188.     int t = 1;
  189.     bool typetest = false;
  190.     if (typetest)
  191.     {
  192.         cin >> t;
  193.     }
  194.     for (int __ = 1; __ <= t; ++ __)
  195.     {
  196.         //cout << "Case " << __ << ": ";
  197.         read();
  198.         solve();
  199.     }
  200. }
  201.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement