#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
using namespace std;
template <typename T>
inline void _read(T& x){
char ch=getchar();bool sign=true;
while(!isdigit(ch)){if(ch=='-')sign=false;ch=getchar();}
for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
if(!sign)x=-x;
}
int n,m,tot;
struct line{
int from,to;
line(){}
line(int x,int y){from=x;to=y;}
};
line edge[300005];
void add_edge(int x,int y){
edge[++tot]=line(x,y);
}
int father[300005],l[300005],r[300005],maxn[300005];
int lazy[300005];
bool rev[300005];
int val[300005];
void update(int x){
maxn[x]=val[x];
if(l[x])maxn[x]=max(maxn[x],maxn[l[x]]);
if(r[x])maxn[x]=max(maxn[x],maxn[r[x]]);
//sum[x]=val[x]+sum[l[x]]+sum[r[x]];
}
void pushdown(int x){
int ls=l[x],rs=r[x];
if(rev[x]){
rev[x]^=1;rev[ls]^=1;rev[rs]^=1;
swap(l[x],r[x]);
}
if(lazy[x]){
if(ls){maxn[ls]+=lazy[x];val[ls]+=lazy[x];lazy[ls]+=lazy[x];}
if(rs){maxn[rs]+=lazy[x];val[rs]+=lazy[x];lazy[rs]+=lazy[x];}
lazy[x]=0;
}
}
void zig(int x){
int y,z;
y=father[x];z=father[y];
if(l[z]==y)l[z]=x;
else if(r[z]==y)r[z]=x;
father[x]=z;
father[y]=x;
father[r[x]]=y;
l[y]=r[x];
r[x]=y;
update(y);update(x);
}
void zag(int x){
int y,z;
y=father[x];z=father[y];
if(l[z]==y)l[z]=x;
else if(r[z]==y)r[z]=x;
father[x]=z;
father[y]=x;
father[l[x]]=y;
r[y]=l[x];
l[x]=y;
update(y);update(x);
}
bool isroot(int x){
return (x!=l[father[x]]&&x!=r[father[x]]);
}
int q[300005];
void splay(int x){
int y,z,top=0,i;
q[++top]=x;
for(i=x;!isroot(i);i=father[i])q[++top]=father[i];
while(top)pushdown(q[top--]);
while(!isroot(x)){
y=father[x];z=father[y];
if(!isroot(y)){
if(l[z]==y){
if(l[y]==x){zig(y);zig(x);}
else {zag(x);zig(x);}
}
else {
if(r[y]==x){zag(y);zag(x);}
else {zig(x);zag(x);}
}
}
else {
if(l[y]==x)zig(x);
else zag(x);
}
}
}
void access(int x){
int i;
for(i=0;x;i=x,x=father[x]){
splay(x);r[x]=i;update(x);
}
}
void setroot(int x){
access(x);splay(x);rev[x]^=1;
}
void link(int x,int y){
setroot(x);
father[x]=y;
}
void cut(int x,int y){
setroot(x);access(y);splay(y);
father[l[y]]=0;l[y]=0;update(y);
}
int find(int x){
access(x);splay(x);
while(l[x])x=l[x];
return x;
}
void add(int x,int y,int d){
setroot(x);access(y);splay(y);
lazy[y]+=d;val[y]+=d;maxn[y]+=d;
}
int query(int x,int y){
setroot(x);access(y);splay(y);
return maxn[y];
}
void clean(){
memset(edge,0,sizeof(edge));
memset(father,0,sizeof(father));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
memset(maxn,0,sizeof(maxn));
memset(rev,0,sizeof(rev));
memset(lazy,0,sizeof(lazy));
memset(val,0,sizeof(val));
}
int main(){
while(scanf("%d",&n)!=EOF&&n!=0){
clean();
int i,j,k;
tot=0;
for(i=1;i<n;i++){
int x,y;
_read(x);_read(y);
add_edge(x,y);
}
for(i=1;i<=n;i++){
_read(val[i]);
maxn[i]=val[i];
}
for(i=1;i<n;i++){
link(edge[i].from,edge[i].to);
}
_read(m);
for(i=1;i<=m;i++){
int x,y,d;
_read(k);
if(k==1){
_read(x);_read(y);
if(find(x)==find(y))puts("-1");
else link(x,y);
}
if(k==2){
_read(x);_read(y);
if(find(x)!=find(y)||x==y)puts("-1");
else cut(x,y);
}
if(k==3){
_read(d);_read(x);_read(y);
if(find(x)!=find(y))puts("-1");
else add(x,y,d);
}
if(k==4){
_read(x);_read(y);
if(find(x)!=find(y))puts("-1");
else printf("%d\n",query(x,y));
}
}
puts("");
}
}
动态树不完整模板---hdu4010 Query on The Trees
最新推荐文章于 2019-03-08 20:07:00 发布