总觉得这个树剖写得不爽 - -
这应该算树剖模板题吧qaq
(原来是zzt太弱了,这题直接线段树搞就可以了,继续%ydc
#include"bits/stdc++.h"
using namespace std;
typedef long long ll;
const int N=100005,LG=20;
vector<int>e[N];
int beg[N],n,dfn[N],bel[N],size[N],deep[N],val[N],fa[N][LG],cnt,m;
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
int dx=deep[x],dy=deep[y],l=dx-dy;
for(int i=0;l;i++)if(l&(1<<i))x=fa[x][i],l^=(1<<i);
for(int i=17;x!=y&&i>=0;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return x==y?x:fa[x][0];
}
void dfs1(int x){
size[x]=1;
for(int i=1;fa[x][i-1];fa[x][i]=fa[fa[x][i-1]][i-1],i++);
for(int i=0;i<e[x].size();i++){
int to=e[x][i];
if(!deep[to]){
deep[to]=deep[x]+1;
fa[to][0]=x;dfs1(to);
size[x]+=size[to];
}
}
}
void dfs2(int x,int b){
bel[x]=b;dfn[x]=++cnt;
val[cnt]=beg[x];int f=-1,siz=0;
for(int i=0;i<e[x].size();i++)
if(size[e[x][i]]>siz&&deep[e[x][i]]>deep[x])
siz=size[e[x][i]],f=e[x][i];
if(f==-1)return;dfs2(f,b);
for(int i=0;i<e[x].size();i++)
if(deep[e[x][i]]>deep[x]&&e[x][i]!=f)
dfs2(e[x][i],e[x][i]);
}
ll sum[4*N],tag[4*N];
void build(int v,int l,int r){
if(l==r){sum[v]=val[l];return;}
int mid=(l+r)>>1,ls=v<<1,rs=ls|1;
build(ls,l,mid);build(rs,mid+1,r);
sum[v]=sum[ls]+sum[rs];
}
void pushdown(int v,int l,int r){
if(l!=r)tag[v<<1]+=tag[v],tag[v<<1|1]+=tag[v];
sum[v]+=(r-l+1)*tag[v];tag[v]=0;
}
void add(int v,int l,int r,int s,int t,int a){
if(l==s&&r==t){tag[v]+=a;pushdown(v,l,r);return;}
int mid=(l+r)>>1,ls=v<<1,rs=ls|1;pushdown(v,l,r);
if(t<=mid)add(ls,l,mid,s,t,a);
else if(s>mid)add(rs,mid+1,r,s,t,a);
else add(ls,l,mid,s,mid,a),add(rs,mid+1,r,mid+1,t,a);
pushdown(ls,l,mid);pushdown(rs,mid+1,r);
sum[v]=sum[ls]+sum[rs];
}
ll qry(int v,int l,int r,int s,int t){
pushdown(v,l,r);
if(l==s&&r==t)return sum[v];
int mid=(l+r)>>1,ls=v<<1,rs=ls|1;
if(t<=mid)return qry(ls,l,mid,s,t);
if(s>mid)return qry(rs,mid+1,r,s,t);
return qry(ls,l,mid,s,mid)+qry(rs,mid+1,r,mid+1,t);
}
ll run(int fr,int to){
ll re=0;
while(bel[fr]!=bel[to]){
re+=qry(1,1,n,dfn[bel[fr]],dfn[fr]);
fr=fa[bel[fr]][0];
}
re+=qry(1,1,n,dfn[to],dfn[fr]);
return re;
}
void work(){
int x,y,f,i,ty;
for(i=1;i<=m;i++){
scanf("%d",&ty);
if(ty<3){
scanf("%d%d",&x,&y);
if(ty==1)add(1,1,n,dfn[x],dfn[x],y);
else add(1,1,n,dfn[x],dfn[x]+size[x]-1,y);
} else{
scanf("%d",&x);
printf("%lld\n",run(x,1));
}
}
}
void pre(){
int i,u,v,c;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&beg[i]);
for(i=1;i<n;i++){
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
deep[1]=1;dfs1(1);dfs2(1,1);
build(1,1,n);
}
int main(){
pre();work();
return 0;
}