思路 :树剖模板,线段树维护即可。
#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; }