hdu 4010 Query on The Trees(LCT裸题)
题目链接:hdu 4010 Query on The Trees
题意:
给你一棵树,有4种操作。
1 连接x,y.
2 断开x,y.
3 将x到y这条路径加上一个值w.
4 询问x到y这条路径的最大值.
题解:
LCT必做题,全是LCT操作。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 #define mst(a,b) memset(a,b,sizeof(a)) 4 using namespace std; 5 6 namespace LCT 7 { 8 const int N=1e5+7; 9 int f[N],son[N][2],val[N],sum[N],tmp[N],lazy[N]; 10 int g[N],v[N*2],nxt[N*2],ed;bool rev[N]; 11 void clear(int n) 12 { 13 F(i,1,n)f[i]=son[i][0]=son[i][1]=0; 14 F(i,1,n)rev[i]=lazy[i]=g[i]=0;ed=0; 15 } 16 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 17 void build(int x=1){ 18 sum[x]=val[x]; 19 for(int i=g[x];i;i=nxt[i]) 20 if(!f[v[i]]&&v[i]!=1)f[v[i]]=x,build(v[i]); 21 } 22 bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;} 23 void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;} 24 void add(int x,int c){if(!x)return;sum[x]+=c,val[x]+=c,lazy[x]+=c;} 25 void pb(int x){ 26 if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0; 27 if(lazy[x])add(son[x][0],lazy[x]),add(son[x][1],lazy[x]),lazy[x]=0; 28 } 29 void up(int x){ 30 sum[x]=val[x]; 31 if(son[x][0])sum[x]=max(sum[son[x][0]],sum[x]); 32 if(son[x][1])sum[x]=max(sum[son[x][1]],sum[x]); 33 } 34 void rotate(int x){ 35 int y=f[x],w=son[y][1]==x; 36 son[y][w]=son[x][w^1]; 37 if(son[x][w^1])f[son[x][w^1]]=y; 38 if(f[y]){ 39 int z=f[y]; 40 if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x; 41 } 42 f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y); 43 } 44 void splay(int x){ 45 int s=1,i=x,y;tmp[1]=i; 46 while(!isroot(i))tmp[++s]=i=f[i]; 47 while(s)pb(tmp[s--]); 48 while(!isroot(x)){ 49 y=f[x]; 50 if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);} 51 rotate(x); 52 } 53 up(x); 54 } 55 void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);} 56 int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;} 57 void makeroot(int x){access(x);splay(x);rev1(x);} 58 void link(int x,int y){makeroot(x);f[x]=y;access(x);} 59 void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);} 60 void cut(int x,int y){makeroot(x);cutf(y);} 61 void update(int x,int y,int c){makeroot(x),access(y),splay(y),add(y,c);} 62 int ask(int x,int y){makeroot(x);access(y);splay(y);return sum[y];} 63 } 64 65 int n,x,y,z,q,op; 66 67 int main() 68 { 69 while(~scanf("%d",&n)) 70 { 71 LCT::clear(n); 72 F(i,2,n) 73 { 74 scanf("%d%d",&x,&y); 75 LCT::adg(x,y),LCT::adg(y,x); 76 } 77 F(i,1,n)scanf("%d",LCT::val+i); 78 LCT::build(); 79 scanf("%d",&q); 80 while(q--) 81 { 82 scanf("%d",&op); 83 if(op==1)//连接x,y 84 { 85 scanf("%d%d",&x,&y); 86 if(LCT::root(x)!=LCT::root(y)) 87 LCT::link(x,y); 88 else puts("-1"); 89 } 90 else if(op==2)//断开x,y 91 { 92 scanf("%d%d",&x,&y); 93 if(LCT::root(x)==LCT::root(y)&&x!=y) 94 LCT::cut(x,y); 95 else puts("-1"); 96 } 97 else if(op==3)//这条链加值 98 { 99 scanf("%d%d%d",&z,&x,&y); 100 if(LCT::root(x)==LCT::root(y)) 101 LCT::update(x,y,z); 102 else puts("-1"); 103 } 104 else //询问这条链 105 { 106 scanf("%d%d",&x,&y); 107 if(LCT::root(x)==LCT::root(y)) 108 printf("%d\n",LCT::ask(x,y)); 109 else puts("-1"); 110 } 111 } 112 puts(""); 113 } 114 return 0; 115 }