zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    个人总结
    找水王
    nabcd需求分析
    四则运算最终篇-网页版四则运算
    第一次冲刺--个人工作总结02
    第一次冲刺--个人工作总结01
    组队APP功能点定点NABCD分析
    水王
    软件工程结对作业01
    个人工作总结06
  • 原文地址:https://www.cnblogs.com/shenben/p/6362831.html
Copyright © 2011-2022 走看看