[BZOJ 1483] [HNOI2009] Dream pudding (segment tree merge)

[BZOJ 1483] [HNOI2009] Dream pudding (segment tree merge)

Face questions

N pudding placed in a row, M times operation each time a pudding full color into another color, and then ask how a total current color segment. E.g. 1,2,2,1 color were four pudding a total of three sections color.

\ (n-, m \ Leq. 1 \ ^. 5 Times 10 \) , color number \ (\ leq 1 \ times 10 ^ 6 \)

analysis

First consider the inquiry, we can find for each color separately continuous segment of this color how many. Weight segment tree can be realized. C the position of the segment tree trees weight maintenance color c occurs, if the color of the i-th position c. A segment tree [i, i] is 1.

So we just look at the number of continuous maintenance intervals segment on it. Each interval to maintain three values: lv, rv, sum, respectively, the left end point is 1, the right end point is 1 and the total number of segments, merge two intervals of time if the right end point if the left and right sections of the left end point of the interval 1, it can spell a period of two consecutive, the answer is the number of segments of the two sections and -1, otherwise the answer into two sections and the number of segments.

The answer (root sum value) segment tree of all colors together, the number of colors is the initial segment.

Then consider modifications. If we become the color of the color x y, equivalent to the combined x to y corresponding segment tree line segment corresponding to the tree, and then remove the tree line x. The combined template is the segment tree merge complexity \ (O (\ log n-) \) , x need only to remove the segment corresponding to the root of the tree can be set to 0, the complexity is \ (O (1) \) of. Always seeking again the answer is clearly time out, we only need to consider a modified variation of the answer operations. Let's subtract segment tree x, y answer, then merged together to answer segment tree y

The total time complexity \ (O (m \ log n ) \)

Code

#include<iostream>
#include<cstdio>
#include<cstring> 
#define maxn 100000
#define maxlogc 25
#define maxc 1000000 
using namespace std;
int n,m;
int a[maxn+5];

struct segment_tree{
//每棵线段树维护一种颜色c的位置出现情况,如果第i个位置颜色为c.则线段树上[i,i]为1 
#define lson(x) tree[x].ls
#define rson(x) tree[x].rs
    struct node{
        int ls;
        int rs;
        int lv;//区间左端点是否为1 
        int rv;//区间右端点是否为1 
        int sum;//总段数 
    }tree[maxn*maxlogc+5];
    int ptr;
    void push_up(int x){
        tree[x].lv=tree[lson(x)].lv;
        tree[x].rv=tree[rson(x)].rv;
        tree[x].sum=tree[lson(x)].sum+tree[rson(x)].sum-(tree[lson(x)].rv==1&&tree[rson(x)].lv==1);
        //如果左区间的右侧和右区间的左侧为1,那么两段可以拼成一段连续的,答案-1 
    }
    void update(int &x,int upos,int l,int r){
        if(!x) x=++ptr;
        if(l==r){
            tree[x].lv=tree[x].rv=tree[x].sum=1;
            return;
        }
        int mid=(l+r)>>1;
        if(upos<=mid) update(tree[x].ls,upos,l,mid);
        else update(tree[x].rs,upos,mid+1,r);
        push_up(x);
    }
    int merge(int x,int y,int l,int r){
        if(!x||!y) return x+y;
        if(l==r){
            tree[x].sum|=tree[y].sum;
            tree[x].lv|=tree[y].lv;
            tree[x].rv|=tree[y].rv;
            return x;
        } 
        int mid=(l+r)>>1;
        tree[x].ls=merge(tree[x].ls,tree[y].ls,l,mid);
        tree[x].rs=merge(tree[x].rs,tree[y].rs,mid+1,r);
        push_up(x);
        return x;
    }
}T;
int root[maxc+5];
int main(){
    int cmd,x,y;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        T.update(root[a[i]],i,1,n);
    }
    int ans=0;
    for(int i=1;i<=maxc;i++) ans+=T.tree[root[i]].sum;
    for(int i=1;i<=m;i++){
        scanf("%d",&cmd);
        if(cmd==1){
            scanf("%d %d",&x,&y);
            if(x==y) continue;
            ans-=T.tree[root[x]].sum;
            ans-=T.tree[root[y]].sum;
            root[y]=T.merge(root[y],root[x],1,n);//一定要写root[y]= 
            ans+=T.tree[root[y]].sum;
            root[x]=0; //记得删除x这棵树 
        }
        else printf("%d\n",ans);
    }
}

Guess you like

Origin www.cnblogs.com/birchtree/p/11314563.html