ll 也开了,不知道为什么。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define N 4000005
#define int long long
using namespace std;
int n,m;
int tot,cnt;
int w[N],head[N],top[N];
int size[N],fa[N],dep[N];
int son[N],idx[N],wt[N];
struct node{
int next,to;
}e[N];
inline void add(int u,int v){
e[++tot].to=v;
e[tot].next=head[u];
head[u]=tot;
}
void dfs1(int u,int f){
dep[u]=dep[f]+1;
fa[u]=f;
size[u]=1;
for(int i=head[u],v;i;i=e[i].next){
v=e[i].to;
if(v==f) continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]])
son[u]=v;
}
}
void dfs2(int u,int topf){
top[u]=topf;
idx[u]=++cnt;
wt[cnt]=w[u];
if(!son[u]) return;
dfs2(son[u],topf);
for(int i=head[u],v;i;i=e[i].next){
v=e[i].to;
if(v==fa[u] || v==son[u]) continue;
dfs2(v,v);
}
}
struct Segment_Tree{
int w[N],lazy[N];
#define lson (k<<1)
#define rson (k<<1|1)
inline void pushup(int k){
w[k]=w[lson]+w[rson];
}
inline void pushdown(int k,int l,int r){
int mid=(l+r)>>1;
lazy[lson]+=lazy[k];
lazy[rson]+=lazy[k];
w[lson]+=lazy[k]*(mid-l+1);
w[rson]+=lazy[k]*(r-mid);
lazy[k]=0;
}
void build(int k,int l,int r){
if(l==r){
w[k]=wt[l];
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(k);
}
void update(int L,int R,int k,int l,int r,int x){
if(l<L || r>R) return;
if(L<=l && r<=R){
lazy[k]+=x;
w[k]+=x*(r-l+1);
return;
}
if(lazy[k]) pushdown(k,l,r);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,lson,l,mid,x);
if(R>mid) update(L,R,rson,mid+1,r,x);
pushup(k);
}
int query(int L,int R,int k,int l,int r){
if(L<=l && r<=R) return w[k];
int mid=(l+r)>>1,res=0;
if(lazy[k]) pushdown(k,l,r);
if(L<=mid) res+=query(L,R,lson,l,mid);
if(R>mid) res+=query(L,R,rson,mid+1,r);
return res;
}
}tree;
inline int qrange(int u,int v){
int res=0ll;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
res+=tree.query(idx[top[u]],idx[u],1,1,n);
u=fa[u];
}
if(dep[u]>dep[v]) swap(u,v);
res+=tree.query(idx[u],idx[v],1,1,n);
return res;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&w[i]);
for(int i=1,u,v;i<n;i++){
scanf("%lld%lld",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,0);
dfs2(1,1);
tree.build(1,1,n);
int opt,u,t;
while(m--){
scanf("%lld",&opt);
if(opt==1){
scanf("%lld%lld",&u,&t);
tree.update(idx[u],idx[u],1,1,n,t);
}
else if(opt==2){
scanf("%lld%lld",&u,&t);
tree.update(idx[u],idx[u]+size[u]-1,1,1,n,t);
}
else{
scanf("%lld",&u);
printf("%lld\n",qrange(1,u));
}
}
return 0;
}