rt(话说为啥打出来是若陀?我该不会染上原神综合征了吧??
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[100005],cnt=0,head[100005];
struct EDGE{
int to,next;
}e[100005<<1|1];
inline void add_edge(int u,int v){
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
int f[100005],sz[100005],son[100005],sgv[100005],seg[100005],tp[100005],segcnt=0;
void dfs1(int now,int fa){
f[now]=fa;
sz[now]++;
for(int i=head[now];i;i=e[i].next){
if(e[i].to==fa)
continue;
dfs1(e[i].to,now);
sz[now]+=sz[e[i].to];
if(sz[e[i].to]>sz[son[now]])
son[now]=e[i].to;
}
}
void dfs2(int now,int t){
tp[now]=t;
seg[sgv[now]=++segcnt]=now;
if(!son[now])
return;
dfs2(son[now],t);
for(int i=head[now];i;i=e[i].next)
if(e[i].to!=f[now]&&e[i].to!=son[now])
dfs2(e[i].to,e[i].to);
}
struct TREE{
int l,r,v,tag;
}t[100005<<2|1];
inline void pushup(int x){t[x].v=t[x<<1].v+t[x<<1|1].v;}
inline void addtag(int x,int l,int r,int w){t[x].tag+=w,t[x].v+=w*(r-l+1);}
inline void pushdown(int x){
if(!t[x].tag)
return;
addtag(x<<1,t[x<<1].l,t[x<<1].r,t[x].tag);
addtag(x<<1|1,t[x<<1|1].l,t[x<<1|1].r,t[x].tag);
t[x].tag=0;
}
void bt(int x,int l,int r){
t[x].l=l,t[x].r=r,t[x].tag=0;
if(l==r){
t[x].v=a[seg[l]];
return;
}
int mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
pushup(x);
}
void upd(int x,int l,int r,int w){
if(l<=t[x].l&&t[x].r<=r)
return addtag(x,t[x].l,t[x].r,w);
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)
upd(x<<1,l,r,w);
if(mid<r)
upd(x<<1|1,l,r,w);
pushup(x);
}
int query(int x,int l,int r){
if(l<=t[x].l&&t[x].r<=r)
return t[x].v;
pushdown(x);
int mid=(t[x].l+t[x].r)>>1,ans=0;
if(l<=mid)
ans+=query(x<<1,l,r);
if(mid<r)
ans+=query(x<<1|1,l,r);
return ans;
}
int op3(int x){
if(x==1)
return query(1,1,1);
int ans=0;
while(x!=1){
ans+=query(1,sgv[tp[x]],sgv[x]);
x=f[tp[x]];
}
return ans;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",a+i);
for(int i=1,u,v;i<n;i++){
scanf("%lld%lld",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs1(1,1);
dfs2(1,1);
bt(1,1,n);
for(int i=1,op,x,y;i<=m;i++){
scanf("%lld%lld",&op,&x);
if(op==1)
scanf("%lld",&y),upd(1,sgv[x],sgv[x],y);
else if(op==2)
scanf("%lld",&y),upd(1,sgv[x],sgv[x]+sz[x]-1,y);
else
printf("%lld\n",op3(x));
}
return 0;
}