Title
https://www.luogu.com.cn/problem/P2590
Solution
板子题
Code
#include<cstdio>
#define rr register
#define ll long long
using namespace std;
const ll N=310000;
const ll M=124000;
ll n,m,Summ,Maxx;
ll seg[N],rev[M],size[N],son[N],top[N],dep[N];
ll sum[M],num[N],father[N],Max[N],tot;
ll first[M],next[M],go[M];
inline void myswap(ll &x,ll &y){x^=y^=x^=y; return;}
inline ll mymax(ll x,ll y){return x>y?x:y;}
inline void add(rr ll x,rr ll y){next[++tot]=first[x],first[x]=tot,go[tot]=y;}
inline void insert(rr ll x,rr ll y){add(x,y); add(y,x);}
inline ll get(){
rr char c;
rr ll sign=1;
while ((c=getchar())<'0'||c>'9')
if (c=='-') sign=-1;
rr ll res=c-'0';
while((c=getchar())>='0'&&c<='9')
res=res*10+c-'0';
return res*sign;
}
inline void build(rr ll k,rr ll l,rr ll r){
rr ll mid=l+r>>1;
if (l==r){
Max[k]=sum[k]=num[rev[l]];
return;
}
build(k<<1,l,mid),build((k<<1)+1,mid+1,r);
sum[k]=sum[k<<1]+sum[(k<<1)+1];
Max[k]=mymax(Max[k<<1],Max[(k<<1)+1]);
return;
}
inline void query(rr ll k,rr ll l,rr ll r,rr ll L,rr ll R){
if (L>r||R<l) return;
if (L<=l&&r<=R){
Summ+=sum[k],Maxx=mymax(Maxx,Max[k]);
return;
}
rr ll mid=l+r>>1,res=0;
if (mid>=L) query(k<<1,l,mid,L,R);
if (mid+1<=R) query((k<<1)+1,mid+1,r,L,R);
return;
}
inline void change(rr ll k,rr ll l,rr ll r,rr ll Val,rr ll pos){
if (pos>r||pos<l) return;
if (l==r&&r==pos){
sum[k]=Val,Max[k]=Val;
return;
}
rr ll mid=l+r>>1;
if (mid>=pos) change(k<<1,l,mid,Val,pos);
if (mid+1<=pos) change((k<<1)+1,mid+1,r,Val,pos);
sum[k]=sum[k<<1]+sum[(k<<1)+1];
Max[k]=mymax(Max[k<<1],Max[(k<<1)+1]);
return;
}
inline void dfs1(rr ll u,rr ll f){
rr ll e,v;
size[u]=1;
father[u]=f;
dep[u]=dep[f]+1;
for(e=first[u];v=go[e],e;e=next[e])
if (v!=f){
dfs1(v,u);
size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
}
return;
}
inline void dfs2(rr ll u,rr ll f){
rr ll e,v;
if (son[u]){
seg[son[u]]=++seg[0];
top[son[u]]=top[u];
rev[seg[0]]=son[u];
dfs2(son[u],u);
}
for(e=first[u];v=go[e],e;e=next[e])
if(!top[v]){
seg[v]=++seg[0];
rev[seg[0]]=v;
top[v]=v;
dfs2(v,u);
}
return;
}
inline void ask(rr ll x,rr ll y){
rr ll fx=top[x],fy=top[y];
while(fx!=fy){
if (dep[fx]<dep[fy]) myswap(x,y),myswap(fx,fy);
query(1,1,seg[0],seg[fx],seg[x]);
x=father[fx]; fx=top[x];
}
if (dep[x]>dep[y]) myswap(x,y);
query(1,1,seg[0],seg[x],seg[y]);
return;
}
inline void write(rr ll x){if (x>9) write(x/10); putchar(x%10+48);}
int main(){
char sr[10];
rr ll i,j,k,u,v,s1,s2;
n=get();
for(i=1;i<n;i++) s1=get(),s2=get(),insert(s1,s2);
for(i=1;i<=n;i++) num[i]=get();
dfs1(1,0);
seg[0]=seg[1]=top[1]=rev[1]=1;
dfs2(1,0);
build(1,1,seg[0]);
m=get();
for(i=1;i<=m;i++){
scanf("%s",sr+1),u=get(),v=get();
if (sr[1]=='C') change(1,1,seg[0],v,seg[u]);
else{
Summ=0,Maxx=-10000000;
ask(u,v);
if (sr[2]=='M') {if (Maxx<0) putchar('-'),write(-Maxx); else write(Maxx); putchar('\n');}
else {if (Summ<0) putchar('-'),write(-Summ); else write(Summ); putchar('\n');}
}
}
return 0;
}