#include<bits/stdc++.h>
using namespace std;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r>>1)
#define N 100005
#define ll long long
struct nd{
ll qz,hz,zd,sum;
nd operator +(const nd b)const{
return {
max(qz,sum+b.qz),
max(hz+b.sum,b.hz),
max(max(zd,b.zd),hz+b.qz),
sum+b.sum};
}
void zhuan(){
swap(qz,hz);
}
}a[N<<2],null;
ll lazy[N<<2];
ll w[N],w2[N];
void build(int p,int l,int r){
if(l==r){
a[p]={max(w[l],0ll),max(0ll,w[l]),max(0ll,w[l]),w[l]};
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
a[p]=a[ls]+a[rs];
return;
}
void ch(int p,int l,int r,ll c){
a[p].zd=a[p].hz=a[p].qz=max((r-l+1)*c,c);
a[p].sum=(r-l+1)*c;
lazy[p]=c;
}
void pushdown(int p,int l,int r){
if(lazy[p]){
ch(ls,l,mid,lazy[p]);
ch(rs,mid+1,r,lazy[p]);
lazy[p]=0;
}
}
void change(int p,int l,int r,int rl,int rr,ll c){
if(l>=rl&&r<=rr){
ch(p,l,r,c);
return;
}
pushdown(p,l,r);
if(rl<=mid) change(ls,l,mid,rl,rr,c);
if(rr>mid) change(rs,mid+1,r,rl,rr,c);
a[p]=a[ls]+a[rs];
}
nd query(int p,int l,int r,int rl,int rr){
if(l>rr||r<rl) return null;
if(l>=rl&&r<=rr) return a[p];
pushdown(p,l,r);
return query(ls,l,mid,rl,rr)+query(rs,mid+1,r,rl,rr);
}
vector<int> v[N];
int n,f[N],deep[N],sz[N],heavy[N],top[N],dfn[N],cnt=0;
void dfs1(int now,int fa){
f[now]=fa;
deep[now]=deep[fa]+1;
sz[now]=1;
for(auto i:v[now]){
if(i==fa) continue;
dfs1(i,now);
sz[now]+=sz[i];
if(sz[i]>sz[heavy[now]]) heavy[now]=i;
}
}
void dfs2(int now,int fa,bool h){
if(h) top[now]=top[fa];
else top[now]=now;
dfn[now]=++cnt;
if(!heavy[now]) return;
dfs2(heavy[now],now,1);
for(auto i:v[now]){
if(dfn[i]) continue;
dfs2(i,now,0);
}
}
void pathC(int x,int y,ll c){
int rtx=top[x],rty=top[y];
while(rtx!=rty){
if(deep[rtx]<deep[rty]){
swap(rtx,rty);swap(x,y);
}
change(1,1,n,dfn[rtx],dfn[x],c);
x=f[rtx];
rtx=top[x];
}
if(deep[x]>deep[y]) swap(x,y);
change(1,1,n,x,y,c);
}
nd pathQ(int x,int y){
//cout<<"pathq"<<x<<" "<<y<<endl;
int rtx=top[x],rty=top[y];
nd ans1=null,ans2=null;
while(rtx!=rty){
if(deep[rtx]<deep[rty]){
ans2=query(1,1,n,dfn[rty],dfn[y])+ans2;
y=f[rty];rty=top[y];
}else{
ans1=query(1,1,n,dfn[rtx],dfn[x])+ans1;
x=f[rtx];rtx=top[x];
}
}
if(deep[x]>deep[y]){
ans1=query(1,1,n,dfn[y],dfn[x])+ans1;
}else ans2=ans2+query(1,1,n,dfn[x],dfn[y]);
ans1.zhuan();
//ans1.debug();ans2.debug();
return ans1+ans2;
}
int main(){
null={-0,-0,-0,0};
cin>>n;
for(int i=1;i<=n;i++) cin>>w2[i];
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(1,1);dfs2(1,1,0);
for(int i=1;i<=n;i++) w[dfn[i]]=w2[i];
build(1,1,n);
int m,op,x,y,c;
cin>>m;
for(int i=1;i<=m;i++){
cin>>op>>x>>y;
if(op==1) cout<<pathQ(x,y).zd<<endl;
else{
cin>>c;
pathC(x,y,c);
}
}
return 0;
}
前面的测试点都没啥问题,就是到 master test 的时候就挂了