RT,输出不同的中间变量可以得到不同的答案。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ls k<<1
#define rs k<<1|1
using namespace std;
inline int read(){
int res=0,f=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
f|=(ch=='-');
ch=getchar();
}
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^'0');
ch=getchar();
}
return f?-res:res;
}
const int maxn=1e5+5;
int n,q,tot,a[maxn],dep[maxn],dfn[maxn],DFN[maxn],son[maxn],top[maxn],siz[maxn],fa[maxn];
vector<int> G[maxn];
void dfs1(int u){
siz[u]=1;
for(int i=0,len=G[u].size();i<len;++i){
int v=G[u][i];
if(v==fa[u])
continue;
dep[v]=dep[u]+1;
fa[v]=u;
dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int t){
dfn[u]=++tot;
DFN[tot]=u;
top[u]=t;
if(son[u])
dfs2(son[u],t);
for(int i=0,len=G[u].size();i<len;++i){
int v=G[u][i];
if(v!=fa[u]&&v!=son[u])
dfs2(v,v);
}
}
struct ST{
int l,r;
int sum;
int lc,rc;
int num;
int tag;
}t[maxn<<2],_;
inline ST Union(ST x,ST b,ST c){
cout<<"b: "<<b.sum<<' '<<b.lc<<' '<<b.rc<<' '<<b.num<<endl;
cout<<"c: "<<c.sum<<' '<<c.lc<<' '<<c.rc<<' '<<c.num<<endl;
ST a=x;
a.sum=b.sum+c.sum;
a.lc=max(b.lc,b.sum+c.lc);
a.rc=max(c.rc,b.rc+c.sum);
a.num=max({b.num,c.num,b.rc+c.lc});
return a;
}
void Build(int k,int l,int r){
t[k].l=l,t[k].r=r,t[k].tag=inf;
if(l==r){
t[k].sum=t[k].num=t[k].lc=t[k].rc=a[DFN[l]];
return;
}
int mid=l+r>>1;
Build(ls,l,mid);
Build(rs,mid+1,r);
t[k]=Union(t[k],t[ls],t[rs]);
}
inline void down(int k){
if(t[k].tag!=inf){
t[ls].tag=t[rs].tag=t[k].tag;
t[ls].sum=(t[ls].r-t[ls].l+1)*t[k].tag;
t[rs].sum=(t[rs].r-t[rs].l+1)*t[k].tag;
if(t[k].tag<0){
t[ls].lc=t[ls].rc=t[k].num=t[k].tag;
t[rs].lc=t[rs].rc=t[k].num=t[k].tag;
} else{
t[ls].lc=t[ls].rc=t[k].num=(t[ls].r-t[ls].l+1)*t[k].tag;
t[rs].lc=t[rs].rc=t[k].num=(t[ls].r-t[ls].l+1)*t[k].tag;
}
t[k].tag=inf;
}
}
ST Query(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r)
return t[k];
down(k);
int mid=t[k].l+t[k].r>>1;
if(mid<l)
return Query(rs,l,r);
if(r<=mid)
return Query(ls,l,r);
return Union(_,Query(ls,l,r),Query(rs,l,r));
}
void Change(int k,int l,int r,int v){
if(l<=t[k].l&&t[k].r<=r){
t[k].tag=v;
t[k].sum=(t[k].r-t[k].l+1)*v;
if(v<0)
t[k].lc=t[k].rc=t[k].num=t[k].tag;
else
t[k].lc=t[k].rc=t[k].num=(t[k].r-t[k].l+1)*v;
return;
}
down(k);
int mid=t[k].l+t[k].r>>1;
if(l<=mid)
Change(ls,l,r,v);
if(mid<r)
Change(rs,l,r,v);
t[k]=Union(t[k],t[ls],t[rs]);
}
inline void Update(int u,int v,int x){
while(top[u]!=top[v]){
if(dep[top[v]]<dep[top[u]])
swap(u,v);
Change(1,dfn[top[v]],dfn[v],x);
v=fa[top[v]];
}
if(dep[v]<dep[u])
swap(u,v);
Change(1,dfn[u],dfn[v],x);
}
inline ST Ask(int u,int v){
ST L,R;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]){
R=Union(_,Query(1,dfn[top[v]],dfn[v]),R);
v=fa[top[v]];
} else{
L=Union(_,Query(1,dfn[top[u]],dfn[u]),L);
u=fa[top[u]];
}
}
if(dep[u]<dep[v])
R=Union(_,Query(1,dfn[u],dfn[v]),R);
else
L=Union(_,Query(1,dfn[v],dfn[u]),L);
swap(L.lc,L.rc);
swap(R.lc,R.rc);
return Union(_,L,R);
}
int main(){
n=read();
for(int i=1;i<=n;++i)
a[i]=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1);
dfs2(1,1);
Build(1,1,n);
q=read();
while(q--){
int op=read();
if(op==1){
int u=read(),v=read();
printf("%d\n",Ask(u,v).num);
} else{
int u=read(),v=read(),x=read();
Update(u,v,x);
}
}
return 0;
}