传送门——BZOJ
传送门——Luogu
刚开始看成区间覆盖以为是一道线段树大水题……语死早
考虑对每一种颜色都建立一棵线段树维护这种颜色的连续子段个数,显然要动态开点
注意要离散化……
两种颜色合并直接线段树合并即可
1 #include<bits/stdc++.h> 2 #define lch (Tree[x].l) 3 #define rch (Tree[x].r) 4 #define mid ((l + r) >> 1) 5 //This code is written by Itst 6 using namespace std; 7 8 inline int read(){ 9 int a = 0; 10 char c = getchar(); 11 bool f = 0; 12 while(!isdigit(c)){ 13 if(c == '-') 14 f = 1; 15 c = getchar(); 16 } 17 while(isdigit(c)){ 18 a = (a << 3) + (a << 1) + (c ^ '0'); 19 c = getchar(); 20 } 21 return f ? -a : a; 22 } 23 24 const int MAXN = 1e5 + 10; 25 struct node{ 26 int l , r , sum; 27 bool ifl , ifr; 28 }Tree[MAXN * 30]; 29 int ans , N , M , cntLSH , cntNode , root[MAXN]; 30 map < int , int > lsh; 31 32 void pushup(int x){ 33 Tree[x].ifl = Tree[lch].ifl; 34 Tree[x].ifr = Tree[rch].ifr; 35 Tree[x].sum = Tree[lch].sum + Tree[rch].sum - (Tree[lch].ifr && Tree[rch].ifl); 36 } 37 38 int merge(int p , int q){ 39 if(!p) 40 return q; 41 if(!q) 42 return p; 43 Tree[p].l = merge(Tree[p].l , Tree[q].l); 44 Tree[p].r = merge(Tree[p].r , Tree[q].r); 45 pushup(p); 46 return p; 47 } 48 49 int insert(int x , int l , int r , int tar){ 50 int t = ++cntNode; 51 Tree[t] = Tree[x]; 52 if(l == r){ 53 Tree[t].ifl = Tree[t].ifr = 1; 54 Tree[t].sum = 1; 55 } 56 else{ 57 if(mid >= tar) 58 Tree[t].l = insert(Tree[t].l , l , mid , tar); 59 else 60 Tree[t].r = insert(Tree[t].r , mid + 1 , r , tar); 61 pushup(t); 62 } 63 return t; 64 } 65 66 int main(){ 67 #ifndef ONLINE_JUDGE 68 freopen("in" , "r" , stdin); 69 freopen("out" , "w" , stdout); 70 #endif 71 N = read(); 72 M = read(); 73 for(int i = 1 ; i <= N ; ++i){ 74 int c = read(); 75 if(!lsh.count(c)) 76 lsh[c] = ++cntLSH; 77 c = lsh[c]; 78 ans -= Tree[root[c]].sum; 79 root[c] = insert(root[c] , 1 , N , i); 80 ans += Tree[root[c]].sum; 81 } 82 while(M--) 83 if(read() == 2) 84 printf("%d\n" , ans); 85 else{ 86 int b = read() , a = read(); 87 if(!lsh.count(b)) 88 continue; 89 if(a == b) 90 continue; 91 if(lsh.count(b) && !lsh.count(a)){ 92 lsh[a] = lsh[b]; 93 lsh.erase(lsh.find(b)); 94 } 95 int t = b; 96 a = lsh[a]; 97 b = lsh[b]; 98 ans -= Tree[root[a]].sum + Tree[root[b]].sum; 99 root[a] = merge(root[a] , root[b]); 100 root[b] = 0; 101 ans += Tree[root[a]].sum; 102 lsh.erase(lsh.find(t)); 103 } 104 return 0; 105 }