Luogu3201/BZOJ1483 HNOI2009 梦幻布丁 线段树合并

传送门——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 }

猜你喜欢

转载自www.cnblogs.com/Itst/p/10178249.html