链接:https://ac.nowcoder.com/acm/contest/5158/I
来源:牛客网
树链剖分的板子题,这里就介绍一篇树链剖分入门的博客吧:https://blog.csdn.net/qq_43326267/article/details/89791152
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; typedef long long ll; struct st{ int to,next; }stm[maxn*2];int head[maxn],cnt; void add(int u,int v){ stm[cnt].to=v; stm[cnt].next=head[u]; head[u]=cnt++; } ll a[maxn]; int tsize[maxn],tson[maxn],top[maxn],rk[maxn],id[maxn],dep[maxn],pre[maxn],co; void init(int n){ for(int i=1;i<=n;i++){ head[i]=-1; tson[i]=0; } co=cnt=0; } struct trem{ ll sum; }tre[maxn<<2]; void dfs1(int now,int fa,int d){ tsize[now]=1; pre[now]=fa; dep[now]=d; // cout<<now<<endl; for(int i=head[now];~i;i=stm[i].next){ int to=stm[i].to; if(to==fa)continue; dfs1(to,now,d+1); tsize[now]+=tsize[to]; if(tsize[to]>tsize[tson[now]])tson[now]=to; } } void dfs2(int now,int Top){ rk[++co]=now; id[now]=co;//编号->dfs序 top[now]=Top; if(tson[now]>0) dfs2(tson[now],Top); for(int i=head[now];~i;i=stm[i].next){ int to=stm[i].to; if(to==pre[now]||to==tson[now])continue; dfs2(to,to); } } void pushup(int rt){ tre[rt].sum=tre[rt<<1].sum+tre[rt<<1|1].sum; return ; } void build(int l,int r,int rt){ if(l==r){ tre[rt].sum=a[rk[l]]; return ; } int mid=(l+r)/2; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } ll query(int l,int r,int lm,int rm,int rt){ if(l<=lm&&r>=rm){ return tre[rt].sum; } ll ans=0; int mid=(lm+rm)/2; if(l<=mid)ans+=query(l,r,lm,mid,rt<<1); if(r>mid)ans+=query(l,r,mid+1,rm,rt<<1|1); return ans; } void update(int l,int r,int pos,ll num,int rt){ if(l==r){ tre[rt].sum+=num; return ; } int mid=(l+r)/2; if(mid>=pos)update(l,mid,pos,num,rt<<1); else update(mid+1,r,pos,num,rt<<1|1); pushup(rt); return ; } int main(){ int n,m,k; int u,v; scanf("%d%d%d",&n,&m,&k); init(n); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs1(k,-1,0); dfs2(k,k); build(1,n,1); int op,pos; ll num; for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%lld",&pos,&num); update(1,n,id[pos],num,1); } else{ scanf("%d",&pos); printf("%lld ",query(id[pos],id[pos]+tsize[pos]-1,1,n,1)); } } return 0; }