萌新刚学树剖,30pts,看了讨论区,发现他们30pts出的错我都没出)
#include <bits/stdc++.h>
using namespace std;
const int N=3e4+10,INF=0x3f3f3f3f;
int n,w[N],q;
struct edge{
int v,nxt;
}e[N*2];
int head[N],cnt=2;
void add(int u,int v){
e[cnt].v=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
int siz[N],fa[N],son[N],dep[N];
int top[N],dfn[N],rnk[N],num=0;
void dfs1(int u,int fat){
siz[u]=1;
fa[u]=fat;
dep[u]=dep[fat]+1;
int mx=-1;
for(int i=head[u];i;i=e[i].nxt){
if(e[i].v!=fat){
dfs1(e[i].v,u);
siz[u]+=siz[e[i].v];
if(siz[e[i].v]>mx){
mx=siz[e[i].v];
son[u]=e[i].v;
}
}
}
}
void dfs2(int u,int topf){
top[u]=topf;
num++;
dfn[u]=num;
rnk[num]=u;
if(!son[u])return;
dfs2(son[u],topf);
for(int i=head[i];i;i=e[i].nxt){
if(!dfn[e[i].v])
dfs2(e[i].v,e[i].v);
}
}
struct node{
int l,r;
int sum,mx;
}t[N*4];
void SegPushup(int p){
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void SegBuild(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].sum=t[p].mx=w[rnk[l]];
return;
}
int m=l+r>>1;
SegBuild(p*2,l,m);
SegBuild(p*2+1,m+1,r);
SegPushup(p);
}
int SegQuerySum(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r)return t[p].sum;
int m=t[p].l+t[p].r>>1,ans=0;
if(l<=m)ans+=SegQuerySum(p*2,l,r);
if(r>m)ans+=SegQuerySum(p*2+1,l,r);
return ans;
}
int SegQueryMax(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r)return t[p].mx;
int m=t[p].l+t[p].r>>1,ans=-INF;
if(l<=m)ans=max(ans,SegQueryMax(p*2,l,r));
if(r>m)ans=max(ans,SegQueryMax(p*2+1,l,r));
return ans;
}
void SegUpdate(int p,int pos,int val){
if(t[p].l==pos&&t[p].r==pos){
t[p].sum=t[p].mx=val;
return;
}
int m=t[p].l+t[p].r>>1;
if(pos<=m)SegUpdate(p*2,pos,val);
if(pos>m)SegUpdate(p*2+1,pos,val);
SegPushup(p);
}
void TreeUpdate(int u,int val){
SegUpdate(1,dfn[u],val);
}
int TreeQueryMax(int u,int v){
int ans=-INF;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=max(ans,SegQueryMax(1,dfn[top[u]],dfn[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans=max(ans,SegQueryMax(1,dfn[u],dfn[v]));
return ans;
}
int TreeQuerySum(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans+=SegQuerySum(1,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans+=SegQuerySum(1,dfn[u],dfn[v]);
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
add(a,b),add(b,a);
}
for(int i=1;i<=n;i++)cin>>w[i];
dfs1(1,0);
dfs2(1,1);
SegBuild(1,1,n);
cin>>q;
while(q--){
char s[10];
int u,v;
cin>>s>>u>>v;
if(s[1]=='H')TreeUpdate(u,v);
if(s[1]=='M')cout<<TreeQueryMax(u,v)<<'\n';
if(s[1]=='S')cout<<TreeQuerySum(u,v)<<'\n';
}
return 0;
}