RT
// Problem: P2590 [ZJOI2008]树的统计
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2590
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)
#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ll (i*2)
#define rr (i*2+1)
string opt;
int n,m,U,V,x,y,cntp;
int a[M],w[M],d[M],top[M],id[M],siz[M],fa[M],son[M];
vector<int>road[M];
struct node
{
int s,fl,fr,xn;
}t[M*9];
void dfs1(int x)
{
if(x==1){d[x]=1;}
siz[x]=1;
int sonm=-1;
for(int i=0;i<road[x].size();i++)
{
if(d[road[x][i]]){continue;}
d[road[x][i]]=d[x]+1;
dfs1(road[x][i]);
fa[road[x][i]]=x;
siz[x]+=siz[road[x][i]];
if(siz[road[x][i]]>sonm)
{
sonm=siz[road[x][i]];
son[x]=road[x][i];
}
}
}
void dfs2(int x,int y)
{
cntp++;
w[cntp]=a[x];
id[x]=cntp;
top[x]=y;
if(son[x]==0){return;}
dfs2(son[x],y);
for(int i=0;i<road[x].size();i++)
{
if(id[road[x][i]]) continue;
dfs2(road[x][i],road[x][i]);
}
}
void build(int l,int r,int i)
{
t[i].fl=l;t[i].fr=r;
if(l==r)
{
t[i].s=w[l];
t[i].xn=w[l];
return;
}
int mid=(l+r)/2;
build(l,mid,ll);
build(mid+1,r,rr);
t[i].s=t[ll].s+t[rr].s;
t[i].xn=max(t[ll].xn,t[rr].xn);
}
node Query(int l,int r,int x,int y,int i)
{
node res,f;res.s=0;res.xn=0;
if(x>=l&&y<=r) return t[i];
int mid=(x+y)/2;
if(mid>=l)
{
f=Query(l,r,x,mid,ll);
res.s+=f.s;
res.xn=max(res.xn,f.xn);
}
if(mid<r)
{
f=Query(l,r,mid+1,y,rr);
res.s+=f.s;
res.xn=max(res.xn,f.xn);
}
return res;
}
void Change(int l,int r,int i)
{
if(l==x&&r==x)
{
t[i].s=y;
t[i].xn=y;
return;
}
int mid=(l+r)/2;
if(mid>=x)
{
Change(l,mid,ll);
}
else
{
Change(mid+1,r,rr);
}
t[i].s=t[ll].s+t[rr].s;
t[i].xn=max(t[ll].xn,t[rr].xn);
}
void Querymax()
{
int res=-10000000;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
res=max(res,Query(id[top[x]],id[x],1,n,1).xn);
x=fa[top[x]];
}
if(d[x]<d[y]) swap(x,y);
res=max(res,Query(id[y],id[x],1,n,1).xn);
cout<<res<<endl;
}
void Querysum()
{
int res=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
res+=Query(id[top[x]],id[x],1,n,1).s;
x=fa[top[x]];
}
if(d[x]<d[y]) swap(x,y);
res+=Query(id[y],id[x],1,n,1).s;
cout<<res<<endl;
}
int main()
{
cin>>n;
for(int i=1;i<n;i++)
{
cin>>U>>V;
road[U].push_back(V);
road[V].push_back(U);
}
for(int i=1;i<=n;i++) cin>>a[i];
dfs1(1);dfs2(1,1);build(1,n,1);
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>opt>>x>>y;
if(opt=="QMAX")
{
Querymax();
}
if(opt=="QSUM")
{
Querysum();
}
if(opt=="CHANGE")
{
Change(1,n,1);
}
}
return 0;
}