注意标记下放时,子节点不为零时再下放,不然统计的时候会出问题……
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 300005
using namespace std;
int fa[maxn],ch[maxn][2];
int val[maxn];
int Max[maxn],add[maxn];
struct lct
{
bool rev[maxn];
void init(int n)
{
for(int i=0;i<=n;i++)
{
rev[i]=0;val[i]=0;
Max[i]=0;add[i]=0;
fa[i]=ch[i][0]=ch[i][1]=0;
}
}
bool dir(int x)
{return x==ch[fa[x]][1];}
bool isroot(int x)
{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void up(int x)
{
Max[x]=val[x];
if(ch[x][0])Max[x]=max(Max[x],Max[ch[x][0]]);
if(ch[x][1])Max[x]=max(Max[x],Max[ch[x][1]]);
}
void rotate(int x)
{
int y=fa[x],z=fa[y];
bool b=dir(x);
int a=ch[x][!b];
if(!isroot(y))
ch[z][dir(y)]=x;
fa[x]=z;ch[x][!b]=y;
fa[y]=x;ch[y][b]=a;
if(a) fa[a]=y;
up(y);up(x);
}
void down(int x)
{
if(rev[x])
{
swap(ch[x][1],ch[x][0]);
rev[ch[x][1]]^=1;
rev[ch[x][0]]^=1;
rev[x]=0;
}
if(add[x])
{
if(ch[x][0]){val[ch[x][0]]+=add[x];Max[ch[x][0]]+=add[x];add[ch[x][0]]+=add[x];}
if(ch[x][1]){val[ch[x][1]]+=add[x];Max[ch[x][1]]+=add[x];add[ch[x][1]]+=add[x];}
add[x]=0;
}
}
int S[maxn],top;
void splay(int x)
{
S[++top]=x;
for(int i=x;!isroot(i);i=fa[i])
S[++top]=fa[i];
while(top) down(S[top--]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(isroot(y)) rotate(x);
else
{
bool b=dir(x),c=dir(y);
if(b^c) {rotate(y);rotate(x);}
else {rotate(x);rotate(x);}
}
}
}
inline void access(int x)
{
for(int t=0;x;t=x,x=fa[x])
splay(x),ch[x][1]=t,up(x);
}
int find(int x)
{
access(x);splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
inline void make_root(int x)
{access(x);splay(x);rev[x]^=1;}
inline void link(int x,int y)
{make_root(x);fa[x]=y;}
inline void cut(int x,int y)
{
make_root(x);access(y);splay(y);
ch[y][0]=fa[ch[y][0]]=0;up(y);
}
void Add(int x,int y,int d)
{
make_root(x);access(y);splay(y);
val[y]+=d;Max[y]+=d;add[y]+=d;
}
int ask(int x,int y)
{
if(find(x)!=find(y))return -1;
make_root(x);access(y);splay(y);
return Max[y];
}
}LCT;
void read(int &a)
{
a=0;int h=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') h=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a*=10;a+=c-'0';
c=getchar();
}
a*=h;
}
struct E{int f,t;}b[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
LCT.init(n);
int u,v;
for(int i=1;i<n;i++)
read(b[i].f),read(b[i].t);
for(int i=1;i<=n;i++)
{
read(val[i]);
Max[i]=val[i];
}
for(int i=1;i<n;i++)
LCT.link(b[i].f,b[i].t);
int m,op,x,y,w;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
read(op);read(x);read(y);
if(op==1)
{
if(LCT.find(x)==LCT.find(y))
{puts("-1");continue;}
LCT.link(x,y);
}
if(op==2)
{
if(x==y||LCT.find(x)!=LCT.find(y))
{puts("-1");continue;}
LCT.cut(x,y);
}
if(op==3)
{
read(w);swap(w,x);
if(LCT.find(x)!=LCT.find(y))
{puts("-1");continue;}
LCT.Add(x,y,w);
}
if(op==4)printf("%d\n",LCT.ask(x,y));
}
puts("");
}
}