zoukankan      html  css  js  c++  java
  • Query on The Trees(hdu 4010)

    题意:

      给出一颗树,有4种操作:

         1、如果x和y不在同一棵树上则在xy连边

         2、如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离

         3、如果x和y在同一棵树上则x到y的路径上所有的点权值+w

         4、如果x和y在同一棵树上则输出x到y路径上的最大值

    /*
      本来一道很水的LCT,结果hdu的提交页面被我刷屏了。。。
      还是too young too simple啊,刚开始不知道多组数据,提交了N次,然后又因为下面的赋值问题提交了N++次。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 300010
    #define inf 1000000000
    using namespace std;
    int fa[N],son[N][2],x[N],y[N],val[N],mx[N],tag[N],rev[N],st[N],n,m;
    void pushdown(int x){
        int l=son[x][0],r=son[x][1];
        if(rev[x]){
            swap(son[x][0],son[x][1]);
            rev[l]^=1;rev[r]^=1;rev[x]^=1;
        }
        if(tag[x]){
            if(l){tag[l]+=tag[x];val[l]+=tag[x];mx[l]+=tag[x];}
            if(r){tag[r]+=tag[x];val[r]+=tag[x];mx[r]+=tag[x];}
            tag[x]=0;
        }
    }
    void pushup(int x){
        int l=son[x][0],r=son[x][1];
        mx[x]=max(val[x],max(mx[l],mx[r]));
    }
    bool isroot(int x){
        return son[fa[x]][0]!=x&&son[fa[x]][1]!=x; 
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],l,r;
        if(son[y][0]==x)l=0;else l=1;r=l^1;
        if(!isroot(y)){
            if(son[z][0]==y) son[z][0]=x;
            else son[z][1]=x;
        }
        fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
        son[y][l]=son[x][r];son[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x){
        int top=0;st[++top]=x;
        for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
        for(int i=top;i;i--) pushdown(st[i]);
        while(!isroot(x)){
            int y=fa[x],z=fa[y];
            if(!isroot(y)){
                if(son[z][0]==y^son[y][0]==x)rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void access(int x){
        int t=0;
        while(x){
            splay(x);
            son[x][1]=t;
            pushup(x);
            t=x;x=fa[x];
        }
    }
    void makeroot(int x){
        access(x);
        splay(x);
        rev[x]^=1;
    }
    void join(int x,int y){
        makeroot(x);
        fa[x]=y;
    }
    void cut(int x,int y){
        makeroot(x);
        access(y);
        splay(y);
        //fa[son[y][0]]=son[y][0]=0;
        //我可能学了假的c++,连从右到左赋值都不知道!!! 
        son[y][0]=fa[son[y][0]]=0;
        pushup(y);
    }
    int find(int x){
        access(x);splay(x);
        int y=x;
        while(son[y][0]) y=son[y][0];
        return y;
    }
    void work(){
        mx[0]=-inf;
        for(int i=1;i<n;i++)scanf("%d%d",&x[i],&y[i]);
        for(int i=1;i<=n;i++)scanf("%d",&val[i]),mx[i]=val[i];
        for(int i=1;i<n;i++)join(x[i],y[i]);
        scanf("%d",&m);
        int opt,x,y,w;
        for(int i=1;i<=m;i++){
            scanf("%d",&opt);
            if(opt==1){
                scanf("%d%d",&x,&y);
                if(find(x)==find(y)){printf("-1
    ");continue;}
                join(x,y);
            }
            else if(opt==2){
                scanf("%d%d",&x,&y);
                if(find(x)!=find(y)||x==y){printf("-1
    ");continue;}
                cut(x,y);
            }
            else if(opt==3){
                scanf("%d%d%d",&w,&x,&y);
                if(find(x)!=find(y)){printf("-1
    ");continue;}
                makeroot(x);access(y);splay(y);
                val[y]+=w;tag[y]+=w;mx[y]+=w;
            }
            else {
                scanf("%d%d",&x,&y);
                if(find(x)!=find(y)){printf("-1
    ");continue;}
                makeroot(x);access(y);splay(y);
                printf("%d
    ",mx[y]);
            }
        }
        printf("
    ");
    }
    int main(){
        while(scanf("%d",&n)!=EOF){
            memset(fa,0,sizeof(fa));
            memset(son,0,sizeof(son));
            memset(val,0,sizeof(val));
            memset(mx,0,sizeof(mx));
            memset(tag,0,sizeof(tag));
            memset(rev,0,sizeof(rev));
            work();
        }
        return 0;
    }
  • 相关阅读:
    抽象类与抽象方法
    PCB设计铜铂厚度、线宽和电流关系
    单层或双层板(PCB)减少环路面积
    电源模块布局考虑因素总结
    传感器信号处理电路
    共模电压和差模电压
    采样电阻选型
    电源防反接保护电路
    MOSFET驱动电路
    自相关与偏自相关
  • 原文地址:https://www.cnblogs.com/harden/p/6414272.html
Copyright © 2011-2022 走看看