CF1140F Extending Set of Points [by the time partition, disjoint-set]

Topic links: Luo Gu

First, we consider the absence of withdrawal operation, is to be seen as each row and each column of a point (called the white dot represents row, on behalf of columns is called black spots), each point $ (x, y) $ regarded as an edge.

Extend operation is actually $ x_1 $ rows and $ y_1, y_2 $ Unicom column, when $ x_2 $ rows and columns of $ y_1 $ Unicom, the line also $ x_2 $ $ $ y_2 row with China Unicom.

Unicom in the same block of a black dot and a white dot will produce a contribution, so that even the sides of query operations + (number of black dots * white point number) of each link block may be used disjoint-set maintain.

Now consider withdrawing operation, in fact, the equivalent of every edge in $ [t_1, t_2] $ this time, "contributing" consider building a tree line about the time, the $ [t_1, t_2] $ split log intervals, and then join these edges corresponding to the edges log intervals concentration within this range indicates the interval of this edge "contribute."

Then, when the segment tree dfs, dfs each time interval to a $ [l, r] $ will set the side edges corresponding to the section added disjoint-set, to eliminate the impact time to exit.

In fact, for most non-amortized time data structures are quickly withdrawn, disjoint-set as well. You can not use path compression, to use the merge by rank.

Time complexity $ (n \ log ^ 2n) O $

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 #define fi first
 4 #define se second
 5 #define mp make_pair
 6 using namespace std;
 7 typedef long long LL;
 8 typedef pair<int, int> pii;
 9 const int N = 600003;
10 int q, fa[N], siz[N][2], top;
11 map<pii, int> ma;
12 vector<pii> vec[N << 2];
13 LL ans, ansx[N];
14 inline int getfa(int x){
15     return x == fa[x] ? x : getfa(fa[x]);
16 }
17 pii que[N];
18 inline void comb(int x, int y){
19     x = getfa(x); y = getfa(y);
20     if(x == y) return;
21     if(siz[x][0] + siz[x][1] < siz[y][0] + [Y] [ 1 ]) swap (x, y);
22      ans + = (LL) [x] [ 0 ] * [y] [ 1 ] + (LL) [x] [ 1 ] * [y] [ 0 ];
23      [x] [ 0 ] + [y] = [ 0 ];
24      [x] [ 1 ] + [y] = [ 1 ];
25      only [y] = x;
26      que [++] = mp (x, y);
28, 27  }
 inline void undo ( int x, int y) {
 29      only [y] = y;
30     you [x] [ 0 ] - = you [y] [ 0 ];
31      you [x] [ 1 ] - = you [y] [ 1 ];
32      ans - = (LL) you [x] [ 0 ] * you [y] [ 1 ] + (LL) you [x] [ 1 ] * you [y] [ 0 ];
33  }
 34 inline void update ( int x, int L int R, int l, int r, PII val) {
 35      if (l <= L && R <= r) {
 36          Vec [x] pushback (plaque) ;
37          return;
38     }
39     int mid = L + R >> 1;
40     if(l <= mid) update(x << 1, L, mid, l, r, val);
41     if(mid < r) update(x << 1 | 1, mid + 1, R, l, r, val);
42 }
43 inline void dfs(int x, int L, int R){
44     int now = top;
45     for(pii tmp : vec[x])
46         comb(tmp.fi, tmp.se);
47     if(L == R) ansx[L] = ans;
48     else {
49         int mid = L + R >> 1;
50         dfs(x << 1, L, mid); dfs(x << 1 | 1, mid + 1, R);
51     }
52     while(top > now){
53         undo(que[top].fi, que[top].se); -- top;
54     }
55 }
56 int main(){
57     scanf("%d", &q);
58     for(Rint i = 1;i <= q;i ++){
59         int x, y;
60         scanf("%d%d", &x, &y); y += 3e5;
61         if(!ma.count(mp(x, y))) ma[mp(x, y)] = i;
62         else {
63             update(1, 1, q, ma[mp(x, y)], i - 1, mp(x, y));
64             ma.erase(mp(x, y));
65         }
66     }
67     for(auto it = ma.begin();it != ma.end();it ++)
68         update(1, 1, q, it -> se, q, it -> fi);
69     for(Rint i = 1;i <= 3e5;i ++) fa[i] = i, siz[i][0] = 1;
70     for(Rint i = 3e5 + 1;i <= 6e5;i ++) fa[i] = i, siz[i][1] = 1;
71     dfs(1, 1, q);
72     for(Rint i = 1;i <= q;i ++) printf("%lld\n", ansx[i]);
73 }
CF1140F

 

Guess you like

Origin www.cnblogs.com/AThousandMoons/p/11116420.html