注意事项:
-
需要的数组:1.建图(ver,nex,head). 2,维护链的数据结构:线段树/树状数组. 3.树剖:dfn,wson,top,size,deep
- dfn[1]=fa[1]=1;
- gai(dfn[x])
- dfs1记录字数大小size/深度d/父节点fa/重儿子wson
- dfs1记录dfn,pre,链顶top
#include<iostream>
#include<stdio.h>
using namespace std;
int g,q,h,i,m,n,j,k,a[100001],nex[100001],head[100001],ver[100001],cnt;
int wson[100005],top[100005],dfn[100001],d[100001],fa[100001],size[100001];
int pre[100005],sum[400010],smm[400011];
char c[10001];
void add(int x,int y)
{
cnt+=1;
ver[cnt]=y;
nex[cnt]=head[x];
head[x]=cnt;
}
void update(int now)
{
sum[now]=sum[now*2]+sum[now*2+1];
smm[now]=max(smm[now*2],smm[now*2+1]);
}
void built(int now,int l,int r)
{
if(l==r) sum[now]=smm[now]=a[pre[l]];
else
{
int mid=(l+r)/2;
built(now*2,l,mid);
built(now*2+1,mid+1,r);
update(now);
}
}
void dfs1(int x,int y)
{
size[x]=1;
for(int i=head[x];i;i=nex[i])
{
int t=ver[i];
if(t==y) continue;
fa[t]=x;
d[t]=d[x]+1;
dfs1(t,x);
if(size[t]>size[wson[x]]) wson[x]=t;
size[x]+=size[t];
}
}
void dfs2(int x,int y)
{
cnt+=1;
dfn[x]=cnt; pre[cnt]=x; top[x]=y;
if(wson[x]) dfs2(wson[x],y);
for(int i=head[x];i;i=nex[i])
{
int t=ver[i];
if(t==fa[x] || t==wson[x]) continue;
dfs2(t,t);
}
}
int qsum(int now,int l,int r,int ll,int rr)
{
if((l>=ll)&&(r<=rr)) return sum[now];
int mid=(l+r)/2,ans=0;
if(ll<=mid) ans+=qsum(now*2,l,mid,ll,rr);
if(rr>mid) ans+=qsum(now*2+1,mid+1,r,ll,rr);
return ans;
}
int qmax(int now,int l,int r,int ll,int rr)
{
if((l>=ll)&&(r<=rr)) return smm[now];
int mid=(l+r)/2,ans=-0x7ffffff;
if(ll<=mid) ans=max(ans,qmax(now*2,l,mid,ll,rr));
if(rr>mid) ans=max(ans,qmax(now*2+1,mid+1,r,ll,rr));
return ans;
}
void gai(int now,int l,int r,int w,int z)
{
if(l==r) sum[now]=smm[now]=z;
else
{
int mid=(l+r)/2,ans=0;
if(mid>=w) gai(now*2,l,mid,w,z);
else gai(now*2+1,mid+1,r,w,z);
update(now);
}
}
int cham(int x,int y)
{
int ans=-0x7fffffff;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
ans=max(qmax(1,1,n,dfn[top[x]],dfn[x]),ans);
x=fa[top[x]];
}
if(d[x]<d[y]) swap(x,y);
ans=max(ans,qmax(1,1,n,dfn[y],dfn[x]));
return ans;
}
int chas(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
ans+=qsum(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(d[x]<d[y]) swap(x,y);
ans+=qsum(1,1,n,dfn[y],dfn[x]);
return ans;
}
int main()
{
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d",&g,&h);
add(g,h);
add(h,g);
}
for(i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);
d[1]=fa[1]=1; cnt=0;
dfs1(1,0); dfs2(1,1); built(1,1,n);
for(i=1;i<=q;i++)
{
scanf("%s%d%d",c,&g,&h);
if(c[1]=='H') gai(1,1,n,dfn[g],h);
if(c[1]=='M') printf("%d
",cham(g,h));
if(c[1]=='S') printf("%d
",chas(g,h));
}
}