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;
    }
  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6574596.html
Copyright © 2011-2022 走看看