我注意到有负数了,而且 CHANGE 操作好像也没问题,为什么 0 分?
#include <iostream>
using namespace std;
#define maxn 100005
typedef long long ll;
ll n,m,fa[maxn],deep[maxn],size[maxn],hson[maxn],top[maxn],dfn[maxn],rnk[maxn],d[maxn],tot,cnt;
ll a[maxn],num[2][maxn*4-1],lazy[maxn*4-1];
struct edge{
ll to,next;
}e[maxn*2];
void addedge(ll u,ll v){
e[++tot].to=v;
e[tot].next=d[u];
d[u]=tot;
}
void dfs1(ll x){
size[x]=1;
for(ll i=d[x];i;i=e[i].next){
if(e[i].to!=fa[x]){
fa[e[i].to]=x;
deep[e[i].to]=deep[x]+1;
dfs1(e[i].to);
size[x]+=size[e[i].to];
if(!hson[x]||size[e[i].to]>size[hson[x]]){
hson[x]=e[i].to;
}
}
}
}
void dfs2(ll x,ll t){
top[x]=t;
dfn[x]=++cnt;
rnk[cnt]=x;
if(!hson[x]){
return;
}
dfs2(hson[x],t);
for(ll i=d[x];i;i=e[i].next){
if(e[i].to!=hson[x]&&e[i].to!=fa[x]){
dfs2(e[i].to,e[i].to);
}
}
}
void build(ll l,ll r,ll root){
if(l==r){
num[0][root]=num[1][root]=a[rnk[l]];
return;
}
ll mid=(l+r)/2;
build(l,mid,root*2);
build(mid+1,r,root*2+1);
num[0][root]=num[0][root*2]+num[0][root*2+1];
num[1][root]=max(num[1][root*2],num[0][root*2+1]);
}
void pushdown(ll l,ll r,ll root){
ll mid=(l+r)/2;
num[0][root*2]=(mid-l+1)*lazy[root];
num[1][root*2]=lazy[root];
lazy[root*2]=lazy[root];
num[0][root*2+1]=(r-mid)*lazy[root];
num[1][root*2+1]=lazy[root];
lazy[root*2+1]=lazy[root];
lazy[root]=0;
}
void change(ll x,ll y,ll k,ll l,ll r,ll root){
if(l>=x&&r<=y){
num[0][root]=(r-l+1)*k;
num[1][root]=k;
lazy[root]=k;
return;
}
if(lazy[root]&&l!=r){
pushdown(l,r,root);
}
ll mid=(l+r)/2;
if(mid>=x){
change(x,y,k,l,mid,root*2);
}
if(mid<y){
change(x,y,k,mid+1,r,root*2+1);
}
num[0][root]=num[0][root*2]+num[0][root*2+1];
num[1][root]=max(num[1][root*2],num[1][root*2+1]);
}
ll get(ll x,ll y,ll l,ll r,ll root,ll mode){
if(l>=x&&r<=y){
return num[mode][root];
}
if(lazy[root]&&l!=r){
pushdown(l,r,root);
}
ll mid=(l+r)/2;
ll ans=(mode?0xbfbfbfbfbfbfbfbf:0);
if(mid>=x){
if(mode){
ans=max(ans,get(x,y,l,mid,root*2,mode));
}
else{
ans+=get(x,y,l,mid,root*2,mode);
}
}
if(mid<y){
if(mode){
ans=max(ans,get(x,y,mid+1,r,root*2+1,mode));
}
else{
ans+=get(x,y,mid+1,r,root*2+1,mode);
}
}
return ans;
}
int main(){
cin>>n;
for(ll i=1;i<n;i++){
ll u,v;
cin>>u>>v;
addedge(u,v);
addedge(v,u);
}
for(ll i=1;i<=n;i++){
cin>>a[i];
}
dfs1(1);
dfs2(1,1);
build(1,n,1);
cin>>m;
for(ll i=1;i<=m;i++){
string op;
cin>>op;
if(op=="CHANGE")
{
ll u,t;
cin>>u>>t;
change(dfn[u],dfn[u],t,1,n,1);
}
else{
ll u,v,ans=(op=="QMAX"?0xbfbfbfbfbfbfbfbf:0);
cin>>u>>v;
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]){
swap(u,v);
}
if(op=="QMAX"){
ans=max(ans,get(dfn[top[u]],dfn[u],1,n,1,1));
}
else{
ans+=get(dfn[top[u]],dfn[u],1,n,1,0);
}
u=fa[top[u]];
}
if(deep[u]<deep[v]){
swap(u,v);
}
if(op=="QMAX"){
ans=max(ans,get(dfn[v],dfn[u],1,n,1,1));
}
else{
ans+=get(dfn[v],dfn[u],1,n,1,0);
}
cout<<ans<<endl;
}
}
return 0;
}