代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e4+5,inf=1e9+5;
int n,m,mid;
int w[MAXN],head[MAXN],x,y,cntedge;
int dep[MAXN],siz[MAXN],son[MAXN],fa[MAXN],dfn[MAXN],rink[MAXN],top[MAXN];//两次深搜所需信息
string s;
int fx,fy;
int u,v,cnt,res;
inline void read(int &number)
{
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') number=-number;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
number=(number<<1)+(number<<3)+(ch-'0');
ch=getchar();
}
return;
}
struct EDGE{
int from,to,pre;
}edge[MAXN<<1];
void add(int from,int to)
{
edge[++cntedge].from=from;
edge[cntedge].to=to;
edge[cntedge].pre=head[from];
head[from]=cntedge;
return;
}
void dfs1(int u,int ufa)
{
dep[u]=dep[ufa]+1;
for(int i=head[u];i;i=edge[i].pre)
{
if(edge[i].to==ufa) continue;
fa[edge[i].to]=u;
dfs1(edge[i].to,u);
siz[u]+=siz[edge[i].to];
if(siz[edge[i].to]>siz[son[u]]) son[u]=edge[i].to;
}
return;
}
void dfs2(int u,int t)
{
top[u]=t;
if(!son[u]) return;
dfn[u]=++cnt;
rink[cnt]=u;
dfs2(son[u],t);
for(int i=head[u];i;i=edge[i].pre)
if(son[u]!=edge[i].to&&edge[i].to!=fa[u]) dfs2(edge[i].to,edge[i].to);//分成若干小树链
return;
}
struct NODE{
int l,r,sum,maxn;//线段树
}node[MAXN<<2];
void build(int l,int r,int p)
{
node[p].l=l,node[p].r=r;
if(l==r)
{
node[p].sum=node[p].maxn=w[rink[l]];
return;
}
mid=(l+r)>>1;
build(l,mid,p<<1);
build(mid+1,r,p<<1|1);
node[p].sum=node[p<<1].sum+node[p<<1|1].sum;
node[p].maxn=max(node[p<<1].maxn,node[p<<1|1].maxn);
return;
}
void upd(int l,int r,int p,int t,int x)
{
if(l==r)
{
node[p].maxn=node[p].sum=t;
return;
}
mid=(l+r)>>1;
if(x<=mid)
upd(l,mid,p<<1,t,x);
else upd(mid+1,r,p<<1|1,t,x);
node[p].sum=node[p<<1].sum+node[p<<1|1].sum;
node[p].maxn=max(node[p<<1].maxn,node[p<<1|1].maxn);
return;
}
int q1(int l,int r,int p,int rl,int rr)
{
if(l>rr||r<rl) return -inf;
if(l<=rl&&r<=rr) return node[p].maxn;
mid=(l+r)>>1;
return max(q1(l,mid,p<<1,rl,rr),q1(mid+1,r,p<<1|1,rl,rr));
}
int q2(int l,int r,int p,int rl,int rr)
{
if(l>rr||r<rl) return 0;
if(rl<=l&&rr<=r) return node[p].sum;
mid=(l+r)>>1;
return q2(l,mid,p<<1,rl,rr)+q2(mid+1,r,p<<1|1,rl,rr);
}
int qmax(int x,int y)
{
res=-inf,fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]>=dep[fy]) res=max(res,q1(1,n,1,dfn[fx],dfn[x])),x=fa[fx];
else res=max(res,q1(1,n,1,dfn[fy],dfn[y])),y=fa[fy];
fx=top[x];
fy=top[y];
}
if(dfn[x]<dfn[y])
res=max(res,q1(1,n,1,dfn[x],dfn[y]));
else res=max(res,q1(1,n,1,dfn[y],dfn[x]));
return res;
}
int qsum(int x,int y)
{
res=0,fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[x]>=dep[y]) res+=max(res,q2(1,n,1,dfn[fx],dfn[x]));
else res+=max(res,q2(1,n,1,dfn[fy],dfn[y]));
fx=top[x];
fy=top[y];
}
return res;
}
int main(){
read(n);
for(int i=1;i<n;i++)
read(x),read(y),add(x,y),add(y,x);
for(int i=1;i<=n;i++)
read(w[i]);
dep[1]=1;
build(1,n,1);
dfs1(1,1);
dfs2(1,1);
read(m);
while(m--)
{
cin >> s;
read(u),read(v);
if(s.find("CHANGE")==0)
upd(1,n,1,v,dfn[u]);
else if(s.find("QMAX")==0)
printf("%d\n",qmax(u,v));
else printf("%d\n",qsum(u,v));
}
return 0;
}
只能说听取RE声一片……