zoukankan      html  css  js  c++  java
  • bzoj3639: Query on a tree VII

    Description

    You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are numbered from 1 to n.

    Each node has a color, white or black, and a weight.

    We will ask you to perfrom some instructions of the following form:

    • u : ask for the maximum weight among the nodes which are connected to u, two nodes are connected iff all the node on the path from u to v (inclusive u and v) have a same color.
    • u : toggle the color of u(that is, from black to white, or from white to black).
    • u w: change the weight of u to w.

    Input

    The first line contains a number n denoted how many nodes in the tree(1 ≤ n ≤ 105). The next n - 1 lines, each line has two numbers (u,  v) describe a edge of the tree(1 ≤ u,  v ≤ n).

    The next 2 lines, each line contains n number, the first line is the initial color of each node(0 or 1), and the second line is the initial weight, let's say Wi, of each node(|Wi| ≤ 109).

    The next line contains a number m denoted how many operations we are going to process(1 ≤ m ≤ 105). The next m lines, each line describe a operation (t,  u) as we mentioned above(0 ≤ t ≤ 2, 1 ≤ u ≤ n|w| ≤ 109).

    Output

    For each query operation, output the corresponding result.

    对原树每个点x,另外拆出两个新点代表黑白,x和x的所有子节点连边到对应的新点,这时重构后得到的树上每个连通块颜色相同,且每次颜色修改只会断开两条边再连上两条边

    然后可以用平衡树维护森林的括号序列,时间复杂度O((n+m)logn)

    #include<cstdio>
    #define G *++ptr
    const int N=100007;
    char buf[N*100],*ptr=buf-1;
    int _(){
        int x=0,c=G,f=1;
        while(c<48)c=='-'&&(f=-1),c=G;
        while(c>47)x=x*10+c-48,c=G;
        return x*f;
    }
    int ch[N*6][5],n;
    int col[N];
    #define lc ch][0
    #define rc ch][1
    #define fa ch][2
    #define val ch][3
    #define mxv ch][4
    int max(int a,int b){return a>b?a:b;}
    void up(int x){
        x[mxv]=max(x[val],max(x[lc][mxv],x[rc][mxv]));
    }
    void rot(int x){
        int f=x[fa],g=f[fa],d=(x!=f[lc]);
        if(g)g[ch][g[lc]!=f]=x;
        x[fa]=g;
        (f[ch][d]=x[ch][d^1])[fa]=f;
        (x[ch][d^1]=f)[fa]=x;
        up(f),up(x);
    }
    void sp(int x,int y=0){
        while(x[fa]!=y){
            int f=x[fa];
            if(f[fa]!=y)rot((f[lc]==x)==(f[fa][lc]==f)?f:x);
            rot(x);
        }
    }
    int gl(int x){
        sp(x);
        while(x[lc])x=x[lc];
        sp(x);
        return x;
    }
    void lk(int x,int y){
        sp(x);sp(y);
        int z=y[rc],xr=x+n*3;
        (y[rc]=x)[fa]=y;
        up(y);
        sp(xr);
        (xr[rc]=z)[fa]=xr;
        up(xr);
    }
    void ct(int x){
        int xr=x+n*3;
        
        sp(x);
        int l=x[lc];
        l[fa]=x[lc]=0;
        up(x);
        
        sp(xr);
        int r=xr[rc];
        r[fa]=xr[rc]=0;
        up(xr);
        
        r=gl(r);
        (r[lc]=l)[fa]=r;
        up(r);
    }
    int F(int w,int t){
        return w+(t+1)*n;
    }
    void init(){
        const int inf=0x3f3f3f3f;
        0[val]=0[mxv]=-inf;
        for(int i=1;i<=n;++i)col[i]=_();
        for(int i=1;i<=n;++i)i[val]=i[mxv]=_();
        for(int i=n+1;i<=n*6;++i)i[val]=i[mxv]=-inf;
        for(int i=1;i<=n*3;++i)(i[rc]=i+n*3)[fa]=i,up(i);
    }
    #undef fa
    int es[N*2],enx[N*2],e0[N],ep=2;
    int fa[N],sz[N],son[N],dep[N],top[N];
    void f1(int w,int pa){
        sz[w]=1;
        dep[w]=dep[fa[w]=pa]+1;
        lk(F(w,col[w]),w);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=pa){
                f1(u,w);
                lk(u,F(w,col[u]));
                sz[w]+=sz[u];
                if(sz[u]>sz[son[w]])son[w]=u;
            }
        }
    }
    void f2(int w,int tp){
        top[w]=tp;
        if(son[w])f2(son[w],tp);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=fa[w]&&u!=son[w])f2(u,u);
        }
    }
    int up(int x,int y){
        int a=top[x],b=top[y];
        while(a!=b){
            x=fa[a];
            if(x==y)return a;
            a=top[x];
        }
        return son[y];
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        n=_();
        for(int i=1,a,b;i<n;++i){
            a=_();b=_();
            es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
            es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
        }
        init();
        f1(1,0);f2(1,1);
        for(int q=_();q;--q){
            int o=_(),w=_();
            if(o==0){
                int l=gl(w);
                if(l>n)w=up(w,(l-1)%n+1);
                else w=1;
                sp(w);
                sp(w+n*3,w);
                printf("%d
    ",max(w[val],(w+n*3)[lc][mxv]));
            }else if(o==1){
                ct(F(w,col[w]));
                lk(F(w,col[w]^1),w);
                if(w!=1){
                    int f=fa[w];
                    ct(w);
                    lk(w,F(f,col[w]^1));
                }
                col[w]^=1;
            }else{
                sp(w);
                w[val]=_();
                up(w);
            }
        }
        return 0;
    }
  • 相关阅读:
    C++中static修饰的静态成员函数、静态数据成员
    C++友元函数、友元类
    C++异常处理
    运行时类型识别RTTI
    AD转换
    敏捷模式下的测试用例该如何存在?
    使用Postman轻松实现接口数据关联
    接口测试Mock利器-moco runner
    python测开平台使用dockerfile构建镜像
    MySQL – 用SHOW STATUS 查看MySQL服务器状态
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6574596.html
Copyright © 2011-2022 走看看