hdu 4010 Query on The Trees

hdu4010
多组测试数据
四个要求:1、把x与y连起来
2、把x转到跟,把y与此时y的父亲切开..(买看清这个..导致一直..mle【再见【再见【再见)
3、把x到y这一条路径都加上z
4、输出x到y这条路径上最大的数

#include 
#include 
using namespace std;
#define N 330000
int n,m,num,fa[N],ch[N][2],ans[N],a[N],flag[N];
bool rev[N];
bool isroot(int x){return x!=ch[fa[x]][0] && x!=ch[fa[x]][1];}
void update(int x){ans[x]=max(a[x],max(ans[ch[x][0]],ans[ch[x][1]]));}
void pushdown(int x){
    if(rev[x]){
        rev[x]^=1;rev[ch[x][1]]^=1;rev[ch[x][0]]^=1;
        swap(ch[x][0],ch[x][1]);
    }if(flag[x]){
        if(ch[x][0]) a[ch[x][0]]+=flag[x],ans[ch[x][0]]+=flag[x],flag[ch[x][0]]+=flag[x];
        if(ch[x][1]) a[ch[x][1]]+=flag[x],ans[ch[x][1]]+=flag[x],flag[ch[x][1]]+=flag[x];
        flag[x]=0;
    }
}
void push(int x){
    if(!isroot(x)) push(fa[x]);
    pushdown(x);
}
void rotate(int x){
    int y=fa[x],z=fa[y],t=ch[y][0]==x;
    if(!isroot(y)) ch[z][ch[z][1]==y]=x;
    fa[y]=x;fa[x]=z;fa[ch[x][t]]=y;
    ch[y][t^1]=ch[x][t];ch[x][t]=y;
    update(y);update(x);
}
void splay(int x){
    push(x); 
    while(!isroot(x)){
        int y=fa[x];
        if(isroot(y)) {rotate(x);return;}
        if(ch[y][0]==x^ch[fa[y]][0]==y) rotate(x);
        else rotate(y); rotate(x);
    }
}
void access(int x){
    int y=0;
    while(x){
        splay(x);ch[x][1]=y;update(x);
        y=x;x=fa[x];
    }
}
void makeroot(int x){
    access(x);splay(x);rev[x]^=1;
}
int find(int x){
    access(x);splay(x);
    while(ch[x][0]) x=ch[x][0];
    return x;
}
void link(int x,int y){
    if(find(x)==find(y)){printf("-1\n");return;}
    makeroot(x);fa[x]=y;
}
void cut(int x,int y){
    if(find(x)!=find(y) || x==y) {printf("-1\n");return;}
    makeroot(x);access(y);splay(y);
    ch[y][0]=fa[ch[y][0]]=0;update(y);
}
void add(int x,int y,int z){
    if(find(x)!=find(y)){printf("-1\n");return;}
    makeroot(x);access(y);splay(y);
    flag[y]+=z;ans[y]+=z;a[y]+=z;
}
void query(int x,int y){
    if(find(x)!=find(y)) {printf("-1\n");return;}
    makeroot(x);access(y);splay(y);printf("%d\n",ans[y]);
}
int main(){
    while(scanf("%d",&n)>0){
        num=0;
        for(int i=0;i<=n;i++) fa[i]=ch[i][0]=ch[i][1]=rev[i]=flag[i]=ans[i]=a[i]=0;
        for(int i=1;iint x,y;scanf("%d%d",&x,&y);
            makeroot(x);fa[x]=y;
        }
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans[i]=a[i];
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            int op,x,y,z;scanf("%d%d%d",&op,&x,&y);
            if(op==1) link(x,y);
            else if(op==2) cut(x,y);
            else if(op==3){
                scanf("%d",&z);
                add(y,z,x);
            }else query(x,y);
        }printf("\n");
    }
    return 0;
} 

你可能感兴趣的:(lct)