| 12
 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
 
 | #include <iostream>#include <cstdio>
 #include <cstring>
 #include <cmath>
 #include <algorithm>
 #include <vector>
 #include <map>
 #include <utility>
 #ifdef XLor
 #define dbg(args...) do {cout << #args << " -> "; err(args);} while (0)
 #else
 #define dbg(...)
 #endif
 void err() {std::cout << std::endl;}
 template<typename T, typename...Args>
 void err(T a, Args...args){std::cout << a << ' '; err(args...);}
 #define lson l, m, rt << 1
 #define rson m + 1, r, rt << 1 | 1
 #define ms(a,b) memset(a,b,sizeof(a))
 using namespace std;
 typedef long long ll;
 typedef pair<int,int> PII;
 const int mod = 998244353;
 const int inf = 1 << 30;
 const int maxn = 300000 + 5;
 
 int pre[maxn << 1], siz[maxn << 1], xcnt[maxn << 1], ycnt[maxn << 1];
 int find(int x) {
 while (x != pre[x]) x = pre[x]; return x;
 }
 ll sum = 0;
 vector<PII> sta;
 bool join(int x, int y) {
 // dbg(x, y);
 x = find(x); y = find(y);
 if (x == y) return 0;
 sum -= 1ll * xcnt[x] * ycnt[x]; sum -= 1ll * xcnt[y] * ycnt[y];
 if (siz[x] > siz[y]) swap(x, y);
 pre[x] = y; siz[y] += siz[x];
 xcnt[y] += xcnt[x]; ycnt[y] += ycnt[x];
 sum += 1ll * xcnt[y] * ycnt[y];
 sta.push_back({x, y});
 return 1;
 }
 void undo() {
 PII tp = sta.back(); sta.pop_back();
 int x = tp.first, y = tp.second;
 pre[x] = x; siz[y] -= siz[x];
 sum -= 1ll * xcnt[y] * ycnt[y];
 xcnt[y] -= xcnt[x]; ycnt[y] -= ycnt[x];
 sum += 1ll * xcnt[x] * ycnt[x]; sum += 1ll * xcnt[y] * ycnt[y];
 }
 
 vector<PII> nodes[maxn << 2];
 void update(int L, int R, PII x, int l, int r, int rt) {
 if (L <= l && r <= R) {
 nodes[rt].push_back(x); return ;
 }
 int m = (l + r) >> 1;
 if (L <= m) update(L, R, x, lson);
 if (R > m) update(L, R, x, rson);
 }
 
 ll ans[maxn];
 void solve(int l, int r, int rt) {
 int cnt = 0;
 // dbg(l, r);
 // for (auto& x: nodes[rt]) dbg(x.first, x.second);
 for (auto& x: nodes[rt]) if (join(x.first, x.second)) cnt++;
 if (l == r) {
 ans[l] = sum;
 for (int i = 0; i < cnt; i++) undo();
 return ;
 }
 int m = (l + r) >> 1;
 solve(lson); solve(rson);
 for (int i = 0; i < cnt; i++) undo();
 }
 
 int n, x[maxn], y[maxn];
 map<PII,int> mp;
 
 int main() {
 scanf("%d", &n);
 for (int i = 1; i <= 2 * n; i++) {
 pre[i] = i; siz[i] = 1;
 xcnt[i] = (i <= n); ycnt[i] = (i > n);
 }
 vector<int> xx, yy;
 for (int i = 1; i <= n; i++) {
 scanf("%d%d", x + i, y + i);
 xx.push_back(x[i]); yy.push_back(y[i]);
 }
 sort(xx.begin(), xx.end()); sort(yy.begin(), yy.end());
 xx.resize(unique(xx.begin(), xx.end()) - xx.begin());
 yy.resize(unique(yy.begin(), yy.end()) - yy.begin());
 for (int i = 1; i <= n; i++) {
 x[i] = lower_bound(xx.begin(), xx.end(), x[i]) - xx.begin() + 1;
 y[i] = lower_bound(yy.begin(), yy.end(), y[i]) - yy.begin() + 1 + n;
 }
 for (int i = 1; i <= n; i++) {
 if (!mp.count({x[i], y[i]}) || mp[{x[i], y[i]}] <= 0) mp[{x[i], y[i]}] = i;
 else {
 update(mp[{x[i], y[i]}], i - 1, {x[i], y[i]}, 1, n, 1);
 mp[{x[i], y[i]}] = -1;
 }
 }
 for (auto& x: mp) if (x.second > 0) update(x.second, n, x.first, 1, n, 1);
 solve(1, n, 1);
 for (int i = 1; i <= n; i++) printf("%I64d ", ans[i]);
 return 0;
 }
 
 |