rt,过不了样例
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
return f*x;
}
int n,q,u,v,x,opt,root=1,a[100005],cnt,top[100005],siz[100005],dep[100005],
dfn[100005],dnf[100005],f[100005],son[100005],head[100005],cnt2;
ll t[200005],lz[200005];
struct edge{
int v,nxt;
}e[200005];
inline void Add(int u,int v){
e[++cnt2].nxt=head[u],e[cnt2].v=v,head[u]=cnt2;
}
void dfs1(int x,int fa){
dep[x]=dep[fa]+1,f[x]=fa,siz[x]=1;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].v^fa)
dfs1(e[i].v,x),siz[x]+=siz[e[i].v],son[x]=(son[x]&&siz[son[x]]>siz[e[i].v]?son[x]:e[i].v);
}
void dfs2(int x,int tp){
dfn[x]=++cnt,dnf[cnt]=x,top[x]=tp;
if(!son[x]) return ;
dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].nxt)
if(!dfn[e[i].v])
dfs2(e[i].v,e[i].v);
}
inline int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=f[top[x]];
}
return dep[x]<dep[y]?x:y;
}
inline int getlca(int x,int y){
int a=lca(x,root),b=lca(y,root),c=lca(x,y);
if(dep[a]<dep[b]) a=b;
if(dep[a]<dep[c]) a=c;
return a;
}
inline int ft(int x,int k){
while(dep[x]-dep[top[x]]<k) k-=(dep[x]-dep[top[x]]+1),x=f[top[x]];
return dnf[dfn[x]-k];
}
void build(int p,int l,int r){
if(l==r){
t[p]=a[dnf[l]];
return ;
}
int mid=l+r>>1;
build(mid<<1,l,mid);
build(mid<<1|1,mid+1,r);
t[p]=t[mid<<1]+t[mid<<1|1];
}
ll query(int p,int l,int r,int lt,int rt){
if(lt<=l&&r<=rt) return t[p];
int mid=l+r>>1;
ll res=0;
if(lz[p])
lz[mid<<1]+=lz[p],lz[mid<<1|1]+=lz[p],t[mid<<1]+=1ll*(mid-l+1)*lz[p],t[mid<<1|1]+=1ll*(r-mid)*lz[p],lz[p]=0;
if(lt<=mid) res+=query(mid<<1,l,mid,lt,rt);
if(rt>mid) res+=query(mid<<1|1,mid+1,r,lt,rt);
return res;
}
void Add(int p,int l,int r,int lt,int rt,int val){
if(lt<=l&&r<=rt){
lz[p]+=val,t[p]+=1ll*(r-l+1)*val;
return ;
}
int mid=l+r>>1;
ll res=0;
if(lz[p])
lz[mid<<1]+=lz[p],lz[mid<<1|1]+=lz[p],t[mid<<1]+=1ll*(mid-l+1)*lz[p],t[mid<<1|1]+=1ll*(r-mid)*lz[p],lz[p]=0;
if(lt<=mid) res+=query(mid<<1,l,mid,lt,rt);
if(rt>mid) res+=query(mid<<1|1,mid+1,r,lt,rt);
t[p]=t[mid<<1]+t[mid<<1|1];
}
inline void upd(int x,int val){
if(root==x)
return Add(1,1,n,1,n,val);
if(lca(root,x)^x)
return Add(1,1,n,dfn[x],dfn[x]+siz[x]-1,val);
int kf=ft(root,dep[root]-dep[x]-1);
Add(1,1,n,1,n,val),Add(1,1,n,dfn[kf],dfn[kf]+siz[kf]-1,-val);
}
inline ll sum(int p){
if(root==p) return t[1];
if(lca(root,p)^p)
return query(1,1,n,dfn[p],dfn[p]+siz[p]-1);
int kf=ft(root,dep[root]-dep[p]-1);
// printf("%d\n",kf);
return t[1]-query(1,1,n,dfn[kf],dfn[kf]+siz[kf]-1);
}
int main(){
n=read(),q=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<n;i++)
u=read(),v=read(),Add(u,v),Add(v,u);
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
// cout<<cnt<<' '<<cnt2<<endl;
// printf("%d\n",ft(4,1));
while(q--){
opt=read();
if(opt==1) root=read();
else if(opt==2){
u=read(),v=read(),x=read();
int lc=getlca(u,v);
// printf("%d\n",lc);
upd(lc,x);
// cout<<"f"<<endl;
}
else v=read(),printf("%lld\n",sum(v));
}
return 0;
}