• 2243: [SDOI2011]染色


    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 6904  Solved: 2562
    [Submit][Status][Discuss]

    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,表示xy之间有一条无向边。

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

    “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

    /*
    维护:
        lcol(当前区间左端点的颜色) 
        rcol(当前区间右端点的颜色) 
        sum(当前区间颜色段数量) 
    合并:
        sum=lson.sum+rson.sum-1{lson.rcol==rson.lcol} 
        sum=lson.sum+rson.sum{lson.rcol!=rson.lcol} 
    */
    #include<cstdio>
    #include<iostream>
    #define lc k<<1
    #define rc k<<1|1
    #define O3 __attribute__((optimize("O3")))
    #define IN inline
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    char in(){
        for(char ch=getchar();;ch=getchar()) if(ch>='A'&&ch<='Z') return ch;
    }
    const int M=1e5+5,N=M<<2;
    struct sgt{int lcol,rcol,sum,tag;}tr[N];
    struct edge{int v,next;}e[N];
    int n,m,tot,cnt,head[M],pos[M],dfn[M],val[M],son[M],top[M],dep[M],fa[M],siz[M];
    IN void add(int x,int y){
        e[++tot].v=y;e[tot].next=head[x];head[x]=tot;
        e[++tot].v=x;e[tot].next=head[y];head[y]=tot;
    }
    O3 void dfs(int x,int f,int de){
        fa[x]=f;dep[x]=de;siz[x]=1;
        for(int i=head[x];i;i=e[i].next){
            if(e[i].v!=f){
                dfs(e[i].v,x,de+1);
                siz[x]+=siz[e[i].v];
                if(!son[x]||siz[son[x]]<siz[e[i].v]) son[x]=e[i].v;
            }
        }
    }
    O3 void getpos(int x,int t1){
        top[x]=t1;pos[x]=++cnt;dfn[cnt]=x;
        if(!son[x]) return ;
        getpos(son[x],t1);
        for(int i=head[x];i;i=e[i].next){
            if(son[x]!=e[i].v&&fa[x]!=e[i].v){
                getpos(e[i].v,e[i].v);
            }
        }
    }
    //=====================================================预处理 
    IN void updata(int k){
        tr[k].lcol=tr[lc].lcol;
        tr[k].rcol=tr[rc].rcol;
        tr[k].sum=tr[lc].sum+tr[rc].sum-(tr[lc].rcol==tr[rc].lcol);
    }
    IN void pushdown(int k){
        if(!tr[k].tag) return ;
        tr[lc].lcol=tr[lc].rcol=tr[k].tag;
        tr[rc].lcol=tr[rc].rcol=tr[k].tag;
        tr[lc].tag=tr[rc].tag=tr[k].tag;
        tr[lc].sum=tr[rc].sum=1;
        tr[k].tag=0;
    }
    O3 void build(int k,int l,int r){
        if(l==r){
            tr[k].lcol=tr[k].rcol=val[dfn[l]];
            tr[k].sum=1;
            return ;
        }
        int mid=l+r>>1;
        build(lc,l,mid);
        build(rc,mid+1,r);
        updata(k);
    }
    O3 void change(int k,int l,int r,int x,int y,int v){
        if(l==x&&r==y){
            tr[k].sum=1;
            tr[k].lcol=tr[k].rcol=tr[k].tag=v;
            return ;
        }
        int mid=l+r>>1;
        pushdown(k);
        if(y<=mid) change(lc,l,mid,x,y,v);
        else if(x>mid) change(rc,mid+1,r,x,y,v);
        else change(lc,l,mid,x,mid,v),change(rc,mid+1,r,mid+1,y,v);
        updata(k);
    }
    O3 int query(int k,int l,int r,int x,int y){
        if(l==x&&r==y) return tr[k].sum;
        pushdown(k);
        int mid=l+r>>1;
        if(y<=mid) return query(lc,l,mid,x,y);
        else if(x>mid) return query(rc,mid+1,r,x,y);
        else{
            int res=query(lc,l,mid,x,mid)+query(rc,mid+1,r,mid+1,y);
            if(tr[lc].rcol==tr[rc].lcol) res--;
            return res;
        }
    }
    O3 int ask_l(int k,int l,int r,int x){
        if(l==r) return tr[k].lcol;
        pushdown(k);
        int mid=l+r>>1;
        if(x<=mid) return ask_l(lc,l,mid,x);
        else return ask_l(rc,mid+1,r,x);
    }
    //=====================================================线段树 
    IN void modify(int x,int y,int c){
        for(;top[x]!=top[y];x=fa[top[x]]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            change(1,1,n,pos[top[x]],pos[x],c);
        }
        //if(x==y) return ;1W
        if(dep[x]>dep[y]) swap(x,y);
        change(1,1,n,pos[x],pos[y],c);
    }
    IN int find(int x,int y){
        int nc,fc,ans=0;
        for(;top[x]!=top[y];x=fa[top[x]]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=query(1,1,n,pos[top[x]],pos[x]);
            nc=ask_l(1,1,n,pos[top[x]]);
            fc=ask_l(1,1,n,pos[fa[top[x]]]);
            if(nc==fc) ans--;
        }
        //if(x==y) return ans;2W
        if(dep[x]>dep[y]) swap(x,y);
        ans+=query(1,1,n,pos[x],pos[y]);
        if(!ans) ans++;
        return ans;
    }
    //=====================================================树链剖分 
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++) val[i]=read();
        for(int i=1,x,y;i<n;i++){
            x=read();y=read();
            add(x,y);
        }
        dfs(1,1,1);
        getpos(1,1);
        build(1,1,n);
        for(int i=1,a,b,c;i<=m;i++){
            c=in();
            if(c=='C'){
                a=read();b=read();c=read();
                modify(a,b,c);
            }
            else{
                a=read();b=read();
                printf("%d
    ",find(a,b));
            }
        }
        return 0;
    }
  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/shenben/p/6362831.html
Copyright © 2020-2023  润新知