#31 [bzoj2243][SDOI2011]染色 树链剖分

Description

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),

如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

Input

第一行包含2个整数n和m,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。

下面 行每行描述一个操作:

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

Output

对于每个询问操作,输出一行答案。

 

Sample Input

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5

Sample Output

3
1
2

HINT

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

Source

思维难度:省选

代码难度:省选

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=100005;
struct node{
    int v,next;
}e[N*2];
struct tree{
    int l,r,x,c,rx,lx;
}t[N*20];
int n,m,cnt,b[N],fa[N],deep[N],sz[N],top[N],son[N],a[N],h[N],tcnt,idx[N],pos[N];
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10;
        x=x+c-'0';
        c=getchar();
    }
    return x*f;
}
void add(int u,int v){
    cnt++;
    e[cnt].v=v;
    e[cnt].next=h[u];
    h[u]=cnt;
}
void dfs1(int u){
    int mxx=0,hv=0;
    sz[u]=1;
    for(int i=h[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(deep[v]!=0)continue;
        deep[v]=deep[u]+1;
        fa[v]=u;
        dfs1(v);
        if(sz[v]>mxx){
            mxx=sz[v];
            hv=v;
        }
        sz[u]+=sz[v];
    }
    son[u]=hv;
}
void dfs2(int u){
    idx[u]=++tcnt;
    a[tcnt]=b[u];
    if(son[u]==0)return;
    top[son[u]]=top[u];
    dfs2(son[u]);
    for(int i=h[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(idx[v])continue;
        top[v]=v;
        dfs2(v);
    }
}
inline int lson(int rt){
    return rt*2;
}
inline int rson(int rt){
    return rt*2+1;
}
inline void pushup(int rt){
    t[rt].lx=t[lson(rt)].lx;t[rt].rx=t[rson(rt)].rx;
    if(t[lson(rt)].rx!=t[rson(rt)].lx){
        t[rt].x=t[lson(rt)].x+t[rson(rt)].x;
    }
    else{
        t[rt].x=t[lson(rt)].x+t[rson(rt)].x-1;
    }
}
void build(int l,int r,int rt){
    t[rt].l=l;t[rt].r=r;t[rt].lx=a[l];t[rt].rx=a[r];
    if(l==r){
        pos[l]=rt;
        t[rt].x=1;
        return;
    }
    int mid=l+r>>1;
    build(l,mid,lson(rt));
    build(mid+1,r,rson(rt));
    pushup(rt);
}
void pushdown(int rt){
    if(t[rt].c==0)return;
    if(t[rt].l==t[rt].r)return;
    t[lson(rt)].x=t[rson(rt)].x=1;
    t[lson(rt)].lx=t[lson(rt)].rx=t[rson(rt)].rx=t[rson(rt)].lx=t[rt].c;
    t[lson(rt)].c=t[rson(rt)].c=t[rt].c;
    t[rt].c=0;
}
void update(int l,int r,int val,int rt){
    if(t[rt].l>=l&&t[rt].r<=r){
        t[rt].x=1;
        t[rt].lx=t[rt].rx=val;
        t[rt].c=val;
        return;
    }
    pushdown(rt);
    int mid=t[rt].l+t[rt].r>>1;
    if(l<=mid){
        update(l,r,val,lson(rt));
    }
    if(r>mid){
        update(l,r,val,rson(rt));
    }
    pushup(rt);
}
int query(int l,int r,int rt){
    if(t[rt].l>=l&&t[rt].r<=r){
        return t[rt].x;
    }
    pushdown(rt);
    int mid=t[rt].l+t[rt].r>>1,ans=0;
    if(l<=mid){
        ans+=query(l,r,lson(rt));
    }
    if(r>mid){
        if(ans){
            if(t[lson(rt)].rx==t[rson(rt)].lx){
                ans--;
            }
        }
        ans+=query(l,r,rson(rt));
    }
    return ans;
}
void T_update(int x,int y,int val){
    int tmp;
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]]){
            tmp=x;x=y;y=tmp;
        }
        update(idx[top[x]],idx[x],val,1);
        x=fa[top[x]];
    }
    if(idx[x]>idx[y]){
        tmp=x;x=y;y=tmp;
    }
    update(idx[x],idx[y],val,1);
}
int T_query(int x,int y){
    int tmp,ans=0;
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]]){
            tmp=x;x=y;y=tmp;
        }
        ans+=query(idx[top[x]],idx[x],1);
        query(idx[top[x]],idx[top[x]],1);
        query(idx[fa[top[x]]],idx[fa[top[x]]],1);
        if(t[pos[idx[top[x]]]].lx==t[pos[idx[fa[top[x]]]]].lx){
            ans--;
        }
        x=fa[top[x]];
    }
    if(idx[x]>idx[y]){
        tmp=x;x=y;y=tmp;
    }
    ans+=query(idx[x],idx[y],1);
    return ans;
}
int main(){
    int u,v,x,y,z;
    char inc[5];
    memset(h,-1,sizeof(h));
    n=read();m=read();
    for(int i=1;i<=n;i++){
        b[i]=read();
    }
    for(int i=1;i<=n-1;i++){
        u=read();v=read();
        add(u,v);
        add(v,u);
    }
    fa[1]=0;deep[1]=1;
    dfs1(1);
    top[1]=1;
    dfs2(1);
    build(1,n,1);
    while(m--){
        scanf("%s",inc);
        if(inc[0]=='Q'){
            x=read();y=read();
            printf("%d\n",T_query(x,y));
        }
        else{
            x=read();y=read();z=read();
            T_update(x,y,z);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LvYanchang/article/details/81660556