1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include<bits/stdc++.h> using namespace std; const int N = 4e5 + 1; int n, q, fa[N], sz[N], line[N], idx, num[N], ans, num2[N]; bool opt[N]; int px[N], py[N]; struct Edge{ int x, y; Edge(int a, int b){ x = a; y = b; } bool operator < (const Edge& other) const{ return x == other.x ? y < other.y : x < other.x; } }; vector<Edge> T[N << 2]; map<Edge, int> mp; int find(int x){ return (x == fa[x] ? x : find(fa[x])); } inline void merge(int x, int y){ int fx = find(x), fy = find(y); if (fx == fy) return line[++idx] = 0, void(); if (sz[fx] > sz[fy]) fx ^= fy ^= fx ^= fy, x ^= y ^= x ^= y; ans--; fa[fx] = fy; line[++idx] = fx; sz[fy] += fx; } inline void rollback(){ int x = line[idx--]; if (!x) return; ans ++; sz[fa[x]] -= sz[x]; fa[x] = x; } void Add(int k, int l, int r, int le, int ri, Edge e){ if (l >= le && r <= ri) return T[k].push_back(e); int mid = l + r >> 1; if (mid >= le) Add(k << 1, l, mid, le, ri, e); if (mid < ri) Add(k << 1 | 1, mid + 1, r, le, ri, e); } void Calc(int k, int l, int r){ for (int i = 0; i < T[k].size(); ++i){ Edge now = T[k][i]; merge(now.x, now.y); } if (l == r) num[l] = ans; else{ int mid = l + r >> 1; Calc(k << 1, l, mid); Calc(k << 1 | 1, mid + 1, r); } for (int i = 0; i < T[k].size(); ++i){ rollback(); } } void clear(int k, int l, int r){ if (l == r) T[k].clear(); int mid = l + r >> 1; clear(k << 1, l, mid); clear(k << 1 | 1, mid + 1, r); } inline int read(){ int x = 0; char ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); return x; } inline bool get(){ char ch = getchar(); while (ch != 'A' && ch != 'B') ch = getchar(); return ch == 'A'; } signed main(){ n = read(), q = read(); for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1; for (int i = 1; i <= q; ++i){ opt[i] = get(), px[i] = read(), py[i] = read(); if (px[i] > py[i]) px[i] ^= py[i] ^= px[i] ^= py[i]; } for (int i = 1; i <= q; ++i){ if (opt[i]){ Edge now = Edge(px[i], py[i]); int pre = mp[now]; if (!pre) mp[now] = i; else{ Add(1, 1, q, pre, i - 1, now); mp.erase(now); } } } for (auto it = mp.begin(); it != mp.end(); ++it){ Edge now = (*it).first; int pre = (*it).second; Add(1, 1, q, pre, q, now); } mp.clear(); ans = n; Calc(1, 1, q); for (int i = 1; i <= q; ++i) num2[i] = num[i]; for (int i = 1; i <= q; ++i){ if (!opt[i]){ Edge now = Edge(px[i], py[i]); int pre = mp[now]; if (!pre) mp[now] = i; else{ Add(1, 1, q, pre, i - 1, now); mp.erase(now); } } } for (auto it = mp.begin(); it != mp.end(); ++it){ Edge now = (*it).first; int pre = (*it).second; Add(1, 1, q, pre, q, now); } mp.clear(); ans = n; Calc(1, 1, q); for (int i = 1; i <= q; ++i){ printf("%d\n", num2[i] - num[i]); } return 0;s }
|