Advertisement
VisualPaul

Persistent DSU (offline)

Mar 11th, 2015
536
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.69 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct edge {
  5.     int op;
  6.     int to;
  7.     edge *next;
  8. };
  9.  
  10. const int N = 100010;
  11. edge *g[N];
  12. int freep;
  13.  
  14. int type[N];
  15. int a[N];
  16. int b[N];
  17. int ans[N];
  18.  
  19. int dsu[N];
  20. int rnk[N];
  21.  
  22. int find_root(int x) {
  23.     while (dsu[x] != x)
  24.         x = dsu[x];
  25.     return x;
  26. }
  27.  
  28. vector<int> st;
  29.  
  30. void unite(int a, int b) {
  31.     a = find_root(a);
  32.     b = find_root(b);
  33.     if (a == b) {
  34.         st.push_back(-1);
  35.         return;
  36.     }
  37.     if (rnk[a] < rnk[b]) {
  38.         swap(a, b);
  39.     }
  40.     dsu[b] = a;
  41.     rnk[a] += rnk[b];
  42.     st.push_back(b);
  43. }
  44.  
  45. void dfs(int v) {
  46.     for (edge *e = g[v]; e; e = e->next) {
  47.         int o = e->op;
  48.         if (type[e->op] == 1) {
  49.             unite(a[o], b[o]);
  50.         } else {
  51.             ans[e->op] = (find_root(a[o]) == find_root(b[o]));
  52.         }
  53.         dfs(e->to);
  54.         if (type[o] == 1) {
  55.             int curV = st.back();
  56.             st.pop_back();
  57.             if (curV != -1) {  
  58.                 int p = dsu[curV];
  59.                 rnk[p] -= rnk[curV];
  60.                 dsu[curV] = curV;
  61.             }
  62.         }  
  63.     }
  64. }
  65.  
  66. int main() {
  67.     int n, m;
  68.     ios_base::sync_with_stdio(false);
  69.     cin.tie(nullptr);
  70.     cin >> n >> m;
  71.     for (int i = 0; i <= n; ++i)
  72.         dsu[i] = i;
  73.     for (int i = 0; i < m; ++i) {
  74.         char tp;
  75.         int old;
  76.         cin >> tp >> old >> a[i] >> b[i];
  77.         type[i] = (tp == '+');
  78.         edge * e = new edge;
  79.         e->op = i;
  80.         e->to = i + 1;
  81.         e->next = g[old];
  82.         g[old] = e;
  83.     }
  84.     dfs(0);
  85.     for (int i = 0; i < m; ++i)
  86.         if (!type[i])
  87.             cout << (ans[i]? "YES" : "NO") << '\n';
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement