#include<bits/stdc++.h>
#define ll int
#define MAXN 200001
using namespace std;
ll n,m,a[MAXN],tag[MAXN<<2];
int nxt[MAXN],head[MAXN],to[MAXN];
ll top[MAXN],fa[MAXN],deep[MAXN],siz[MAXN],id[MAXN],zh[MAXN],c[MAXN];
ll dot1;
ll cnt;
ll cntt=-1;
ll dd;
struct st{
ll x=0;
ll m=0;
ll l=0;
ll r=0;
}ans[MAXN<<2];
//vector<st> q,qq;
//vector<ll> qr;
ll dot;
ll s;
ll ma;
bool bq;
inline void add(int u,int v){
nxt[++cntt]=head[u];
head[u]=cntt;
to[cntt]=v;
swap(u,v);
nxt[++cntt]=head[u];
head[u]=cntt;
to[cntt]=v;
return;
}
inline ll ls(ll x){
return x<<1;
}
inline ll rs(ll y){
return y<<1|1;
}
/*inline void f(ll p,ll l,ll r,ll k){
tag[p]=tag[p]+k;
ans[p]=ans[p]+k*(r-l+1);
}*/
st merge(st x,st y) {
st an;
an.x=x.x+y.x;
an.l=max(x.l,x.x+y.l);
an.r=max(y.r,y.x+x.r);
an.m=max(max(x.m,y.m),x.r+y.l);
return an;
}
void in(){
cin>>n;
for(register int i=1;i<=n;i++)
scanf("%d",&c[i]);
int x,y;
for(register int i=1;i<=n-1;i++){
scanf("%d%d",&x,&y);
add(x,y);
}
cin>>m;
return;
}
inline void push_up(ll p){
ans[p].x=ans[rs(p)].x+ans[ls(p)].x;
ans[p].m=max(max(ans[rs(p)].l+ans[ls(p)].r,ans[p].x),max(ans[rs(p)].m,ans[ls(p)].m));
ans[p].l=max(ans[ls(p)].x+ans[rs(p)].l,ans[ls(p)].l);
ans[p].r=max(ans[rs(p)].x+ans[ls(p)].r,ans[rs(p)].r);
return;
}
inline void push_down(ll p,ll l,ll r){
ll mid=(l+r)>>1;
ll k=tag[p];
int rr=rs(p),lr=ls(p);
ans[rr].x=k*(r-mid);
ans[rr].m=ans[rr].r=ans[rr].l=max(0,ans[rr].x);
tag[rr]=k;
ans[lr].x=k*(mid-l+1);
ans[lr].m=ans[lr].l=ans[lr].r=max(0,ans[lr].x);
tag[lr]=k;
tag[p]=0;
return;
}
void build(ll p,ll l,ll r){
tag[p]=0;
if(l==r){
ans[p].x=a[l]*(r-l+1);
ans[p].m=ans[p].r=ans[p].l=max(0,ans[p].x);
tag[p]=a[l];
//cout<<l<<" "<<a[l]<<endl;
return;
}
ll mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
ans[p]=merge(ans[ls(p)],ans[rs(p)]);
return;
}
inline void update(ll l1,ll r1,ll l,ll r,ll p,ll k){
if(l1<=l&&r<=r1){
ans[p].x=k*(r-l+1);
ans[p].m=ans[p].r=ans[p].l=max(0,ans[p].x);
tag[p]=k;
//cout<<l<<" "<<r<<endl;
return;
}
if(tag[p]) push_down(p,l,r);
ll mid=(l+r)>>1;
if(l1<=mid) update(l1,r1,l,mid,ls(p),k);
if(r1>mid) update(l1,r1,mid+1,r,rs(p),k);
ans[p]=merge(ans[ls(p)],ans[rs(p)]);
return;
}
inline st query(ll x,ll y,ll l,ll r,ll p){
if(x<=l&&y>=r){
//cout<<ans[p].x<<" "<<x<<" "<<y<<endl;
return ans[p];
}
st L,R;
ll mid=(l+r)>>1;
if(tag[p]) push_down(p,l,r);
if(x<=mid) L=query(x,y,l,mid,ls(p));
if(y>mid) R=query(x,y,mid+1,r,rs(p));
return merge(L,R);
}
inline void dfs1(int f,int p,int d){
deep[p]=d;
fa[p]=f;
siz[p]=1;int maz=-1;
for(register int i=head[p];~i;i=nxt[i]){
if(to[i]==f) continue;
else{
dfs1(p,to[i],d+1);
if(siz[to[i]]>maz) zh[p]=to[i];
siz[p]+=siz[to[i]];
}
}
return;
}
inline void dfs2(int too,int p){
top[p]=too;
id[p]=++cnt;
a[id[p]]=c[p];
if(siz[p]>1) dfs2(too,zh[p]);
else return;
for(register int i=head[p];~i;i=nxt[i]){
if(to[i]==fa[p]||to[i]==zh[p]) continue;
else{
dfs2(to[i],to[i]);
}
}
return;
}
inline void upd1(int x,int y,int k){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
update(id[top[x]],id[x],1,n,1,k);
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
update(id[x],id[y],1,n,1,k);
return;
}
st que1(int u,int v) {
st L,R;
for(int fu=top[u],fv=top[v];fu^fv;) {
if(deep[fu]<deep[fv]) {
R=merge(query(id[fv],id[v],1,n,1),R);
v=fa[fv],fv=top[v];
} else {
L=merge(query(id[fu],id[u],1,n,1),L);
u=fa[fu],fu=top[u];
}
}
if(deep[u]>deep[v]) {
L=merge(query(id[v],id[u],1,n,1),L);
} else {
R=merge(query(id[u],id[v],1,n,1),R);
}
swap(L.l,L.r);
return merge(L,R);
}
int main(){
int a1,b1,c1,d1,e1,f1;
memset(to,-1,sizeof to);
memset(head,-1,sizeof head);
memset(nxt,-1,sizeof nxt);
in();
dfs1(1,1,1);
dfs2(1,1);
//for(int i=1;i<=n;i++) cout<<zh[i]<<" ";
//cout<<endl;
build(1,1,n);
//cout<<111<<endl;
while(m--){
scanf("%d",&a1);
if(a1==1){
scanf("%d%d",&b1,&d1);
printf("%d\n",que1(b1,d1).m);
}
else{
scanf("%d%d%d",&e1,&f1,&c1);
upd1(e1,f1,c1);
}
}
return 0;
}
树链加线段树 但是tle了 球调((