思路 :树剖模板,线段树维护即可。
#include<bits/stdc++.h>
using namespace std;
#define MID int m = (l+r)/2
#define maxn 56789
#define inf 0x3f3f3f3f
int data[maxn],n,m,id[maxn],fa[maxn],u,ans,head[maxn];
int son[maxn],top[maxn],tid[maxn],cnt,v,ad;
int deep[maxn],siz[maxn],id_data[maxn],q,ss;
struct node
{
int sum,lazy,cnt,big;
node()
{
sum=lazy=cnt=0;
big=-inf;
}
node operator+(const node &a)const
{
node ret;
ret.sum=a.sum+sum;
ret.cnt=a.cnt+cnt;
ret.big=max(a.big,big);
return ret;
}
} tree[maxn*4];
struct edg
{
int v,to;
} edge[maxn*2];
char str[12];
void add(int u,int v)
{
edge[++ss].v=v;
edge[ss].to=head[u];
head[u]=ss;
}
void bulid(int root,int l,int r)
{
tree[root].big=-inf;
if(l==r)
{
tree[root].big=tree[root].sum=id_data[l];
return ;
}
MID;
bulid(root*2,l,m);
bulid(root*2+1,m+1,r);
tree[root]=tree[root*2]+tree[root*2+1];
}
void updata(int root,int l,int r,int L,int R,int ad)
{
if(r<L||l>R)return;
if(L<=l&&r<=R)
{
tree[root].sum=tree[root].big=ad;
return ;
}
MID;
updata(root*2,l,m,L,R,ad);
updata(root*2+1,m+1,r,L,R,ad);
tree[root]=tree[root*2]+tree[root*2+1];
}
void query1(int root,int l,int r,int L,int R)
{
if(r<L||l>R)return ;
if(L<=l&&r<=R)
{
ans+=tree[root].sum;
return;
}
MID;
query1(root*2,l,m,L,R);
query1(root*2+1,m+1,r,L,R);
}
void query2(int root,int l,int r,int L,int R)
{
if(r<L||l>R)return ;
if(L<=l&&r<=R)
{
ans=max(ans,tree[root].big);
return;
}
MID;
query2(root*2,l,m,L,R);
query2(root*2+1,m+1,r,L,R);
}
void dfs1(int u,int pre,int ide)
{
son[u]=-1,siz[u]=1;
deep[u]=ide,fa[u]=pre;
for(int i=head[u]; i!=-1; i=edge[i].to)
{
int v=edge[i].v;
if(v==pre)continue;
dfs1(v,u,ide+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp, tid[u]=++cnt;
id_data[cnt]=data[u];
if(son[u]!=-1)dfs2(son[u],tp);
for(int i=head[u]; i!=-1; i=edge[i].to)
{
int v=edge[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void solve(int x,int y,int ad)
{
int tx=top[x],ty=top[y];
while(tx!=ty)
{
if(deep[tx]<deep[ty])swap(x,y),swap(tx,ty);
if(ad==1)
query1(1,1,n,tid[tx],tid[x]);
else query2(1,1,n,tid[tx],tid[x]);
x=fa[tx],tx=top[x];
}
if(deep[x]<deep[y])swap(x,y);
if(ad==1)
query1(1,1,n,tid[y],tid[x]);
else query2(1,1,n,tid[y],tid[x]);
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1; i<n; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1; i<=n; i++)
scanf("%d",&data[i]);
dfs1(1,0,1);
dfs2(1,1);
bulid(1,1,n);
scanf("%d",&q);
while(q--)
{
scanf("%s",str);
if(str[0]=='C')
{
scanf("%d%d",&u,&ad);
updata(1,1,n,tid[u],tid[u],ad);
}
else if(str[1]=='M')
{
scanf("%d%d",&u,&v);
ans=-inf;
solve(u,v,2);
printf("%d\n",ans);
}
else
{
scanf("%d%d",&u,&v);
ans=0;
solve(u,v,1);
printf("%d\n",ans);
}
}
return 0;
}