更新英文是 update 而不是 updata
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10,M=2e5+10;
int n,m;
int h[N],e[M*2],ne[M*2],idx;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dep[N],fa[N],sz[N],top[N],son[N];
int id[N],cnt;
ll w[N],nw[N];
struct Nd{
int l,r;
ll add,v;
}tr[N*4];
void dfs1(int u,int father,int depth){
dep[u]=depth,fa[u]=father,sz[u]=1;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==father) continue;
dfs1(j,u,depth+1);
sz[u]+=sz[j];
if(sz[j]>sz[son[u]]) son[u]=j;
}
}
void dfs2(int u,int t){
id[u]=++cnt,nw[cnt]=w[u],top[u]=t;
if(!son[u]) return;
dfs2(son[u],t);
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(j==fa[u]||j==son[u]) continue;
dfs2(j,j);
}
}
void pushup(int u){
tr[u].v=tr[u<<1].v+tr[u<<1|1].v;
}
void pushdown(int u){
Nd &rt=tr[u],&lc=tr[u<<1],&rc=tr[u<<1|1];
if(!rt.add) return;
lc.add+=rt.add;rc.add+=rt.add;
lc.v+=(lc.r-lc.l+1)*rt.add;
rc.v+=(rc.r-rc.l+1)*rt.add;
rt.add=0;
}
void build(int u,int l,int r){
tr[u]={l,r,0,nw[r]};
if(l==r) return;
int mid=l+r>>1;
build(u<<1,l,mid);build(u<<1|1,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,ll k){
if(tr[u].l>r||tr[u].r<l) return;
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].add+=k;
tr[u].v+=(ll)(tr[u].r-tr[u].l+1)*k;
return;
}
pushdown(u);
update(u<<1,l,r,k);update(u<<1|1,l,r,k);
pushup(u);
}
ll query(int u,int l,int r){
if(tr[u].l>r||tr[u].r<l) return 0;
if(tr[u].l>=l&&tr[u].r<=r) return tr[u].v;
pushdown(u);
return query(u<<1,l,r)+query(u<<1|1,l,r);
pushup(u);
}
void update_path(int u,int v,int k){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(1,id[top[u]],id[u],k);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
update(1,id[v],id[u],k);
}
ll get_path(int u,int v){
ll res=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=query(1,id[top[u]],id[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
res+=query(1,id[v],id[u]);
return res;
}
ll get_tree(int u){
return query(1,id[u],id[u]+sz[u]-1);
}
void update_tree(int u,ll k){
update(1,id[u],id[u]+sz[u]-1,k);
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
memset(h,-1,sizeof(h));int a,b;
for(int i=1;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs1(1,-1,1);dfs2(1,1);build(1,1,n);
scanf("%d",&m);
while(m--){
int t,u,v,k;
scanf("%d%d",&t,&u);
if(t==1){
scanf("%d%d",&v,&k);
update_path(u,v,k);
}
else if(t==2){
scanf("%d",&k);
update_tree(u,k);
}
else if(t==3){
scanf("%d",&v);
printf("%lld\n",get_path(u,v));
}
else printf("%lld\n",get_tree(u));
}
return 0;
}