Advertisement
Guest User

Untitled

a guest
Jan 13th, 2021
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.38 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #ifdef LOCAL
  4. #include "trace.h"
  5. #else
  6. #define trace(args...)
  7. #endif
  8.  
  9. using ll = long long;
  10. using ld = long double;
  11. using pii = pair<int, int>;
  12. using ppi = pair<pii, pii>;
  13. using vi = vector<int>;
  14. #define mp make_pair
  15. #define ub upper_bound
  16. #define lb lower_bound
  17. #define fi first
  18. #define se second
  19. #define pb push_back
  20. #define eb emplace_back
  21. #define all(v) (v).begin(), (v).end()
  22. #define rall(v) (v).rbegin(), (v).rend()
  23.  
  24. struct PersistentDSU {
  25.     int comp;
  26.     stack<int> states;
  27.     vector<int> siz, par;
  28.     PersistentDSU(int n = 0) {
  29.         comp = n;
  30.         par.resize(n);
  31.         siz.assign(n, 1);
  32.         for (int i = 0; i < n; i++) {
  33.             par[i] = i;
  34.         }
  35.     }
  36.     int root(int a) {
  37.         while (a != par[a])
  38.             a = par[a];
  39.         return a;
  40.     }
  41.     int unite(int a, int b) {
  42.         a = root(a), b = root(b);
  43.         if (a == b) return 0;
  44.         if (siz[a] > siz[b])
  45.             swap(a, b);
  46.         states.push(a);
  47.         siz[b] += siz[a];
  48.         par[a] = b;
  49.         comp--;
  50.         return 1;
  51.     }
  52.     bool rollback(int cnt = 1) {
  53.         while (cnt--) {
  54.             if (states.empty())
  55.                 return false;
  56.             int s = states.top();
  57.             states.pop();
  58.             siz[par[s]] -= siz[s];
  59.             par[s] = s;
  60.             comp++;
  61.         }
  62.         return true;
  63.     }
  64. };
  65.  
  66. PersistentDSU dsu;
  67. vector<int> ans;
  68.  
  69. const int N = 3e5 + 1;
  70. vector<pii> segs[4 * N];
  71.  
  72. void add(int v, int tl, int tr, int l, int r, pii p) {
  73.     if (max(l, tl) >= min(r, tr))
  74.         return;
  75.     if (l <= tl && tr <= r) {
  76.         segs[v].eb(p);
  77.         trace(tl, tr, p);
  78.         return;
  79.     }
  80.     int m = (tl + tr) / 2;
  81.     add(v * 2, tl, m, l, r, p);
  82.     add(v * 2 + 1, m, tr, l, r, p);
  83. }
  84. void rec(int v, int l, int r) {
  85.     int cnt = 0, m = (l + r) / 2;
  86.     for (pii p : segs[v])
  87.         cnt += dsu.unite(p.fi, p.se);
  88.     if (l == r - 1) {
  89.         if (ans[l] == -2)
  90.             ans[l] = dsu.comp;
  91.     } else {
  92.         rec(v * 2, l, m);
  93.         rec(v * 2 + 1, m, r);
  94.     }
  95.     dsu.rollback(cnt);
  96. }
  97. void solve(int test) {
  98.     int n, m;
  99.     cin >> n >> m;
  100.  
  101.     map<pii, int> edges;
  102.     ans.assign(m, -1);
  103.  
  104.     for (int i = 0; i < m; i++) {
  105.         string t;
  106.         cin >> t;
  107.         trace(t);
  108.         if (t == "?") {
  109.             ans[i] = -2;
  110.             continue;
  111.         }
  112.         int x, y;
  113.         cin >> x >> y;
  114.         pii p = mp(--x, --y);
  115.  
  116.         auto it = edges.find(p);
  117.         if (it == edges.end()) {
  118.             edges[p] = -1;
  119.             it = edges.find(p);
  120.         }
  121.  
  122.         if (t == "+") {
  123.             if (it->se == -1)
  124.                 it->se = i;
  125.         }
  126.         if (t == "-") {
  127.             if (it->se != -1) {
  128.                 add(1, 0, m, it->se, i, p);
  129.                 it->se = -1;
  130.             }
  131.         }
  132.     }
  133.     int cnt = m;
  134.     for (auto pp : edges)
  135.         if (pp.se != -1)
  136.             add(1, 0, m, pp.se, cnt++, pp.fi);
  137.     edges.clear();
  138.  
  139.     dsu = PersistentDSU(n);
  140.     rec(1, 0, m);
  141.  
  142.     for (int i : ans)
  143.         if (i != -1)
  144.             cout << i << '\n';
  145. }
  146.  
  147. int main() {
  148.     ios_base::sync_with_stdio(false);
  149.     cin.tie(NULL);
  150.     cout.tie(NULL);
  151.     int t = 1;
  152.     // cin >> t;
  153.     for (int i = 1; i <= t; i++) {
  154.         // cout << "Case #" << i << ": ";
  155.         solve(i);
  156.     }
  157. }
  158.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement