洛谷 3178 [HAOI2015]树上操作
【题解】
就是个树链剖分的模板题。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 #define rg register 6 #define N 200010 7 #define ls (u<<1) 8 #define rs (u<<1|1) 9 #define mid ((a[u].l+a[u].r)>>1) 10 using namespace std; 11 int n,m,tot,cnt,opt,last[N],fa[N],hvy[N],top[N],dep[N],dfn[N],siz[N],poi[N],v[N]; 12 struct edge{ 13 int to,pre; 14 }e[N<<1]; 15 struct tree{ 16 int l,r; LL sum,del; 17 }a[N<<2]; 18 inline int read(){ 19 int k=0,f=1; char c=getchar(); 20 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 21 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 22 return k*f; 23 } 24 void dfs1(int x){ 25 siz[x]=1; dep[x]=dep[fa[x]]+1; 26 for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]){ 27 fa[to]=x; dfs1(to); siz[x]+=siz[to]; 28 if(siz[to]>siz[hvy[x]]) hvy[x]=to; 29 } 30 } 31 void dfs2(int x,int tp){ 32 top[x]=tp; dfn[x]=++cnt; poi[cnt]=x; 33 if(hvy[x]) dfs2(hvy[x],tp); 34 for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]&&to!=hvy[x]) 35 dfs2(to,to); 36 } 37 void build(int u,int l,int r){ 38 a[u].l=l; a[u].r=r; 39 if(l<r) build(ls,l,mid),build(rs,mid+1,r),a[u].sum=a[ls].sum+a[rs].sum; 40 else a[u].sum=v[poi[l]]; 41 } 42 inline void pushdown(int u){ 43 LL d=a[u].del; a[u].del=0; 44 a[ls].sum+=1LL*d*(a[ls].r-a[ls].l+1); a[ls].del+=d; 45 a[rs].sum+=1LL*d*(a[rs].r-a[rs].l+1); a[rs].del+=d; 46 } 47 void update(int u,int l,int r,LL del){ 48 if(l<=a[u].l&&a[u].r<=r){ 49 a[u].sum+=1LL*del*(a[u].r-a[u].l+1); 50 a[u].del+=del; 51 return; 52 } 53 if(a[u].del) pushdown(u); 54 if(l<=mid) update(ls,l,r,del); 55 if(r>mid) update(rs,l,r,del); 56 a[u].sum=a[ls].sum+a[rs].sum; 57 } 58 LL query(int u,int l,int r){ 59 if(l<=a[u].l&&a[u].r<=r) return a[u].sum; 60 if(a[u].del) pushdown(u); LL ret=0; 61 if(l<=mid) ret+=query(ls,l,r); 62 if(r>mid) ret+=query(rs,l,r); 63 return ret; 64 } 65 int main(){ 66 n=read(); m=read(); 67 for(rg int i=1;i<=n;i++) v[i]=read(); 68 for(rg int i=1;i<n;i++){ 69 int u=read(),v=read(); 70 e[++tot]=(edge){v,last[u]}; last[u]=tot; 71 e[++tot]=(edge){u,last[v]}; last[v]=tot; 72 } 73 dfs1(1); dfs2(1,1); build(1,1,n); 74 while(m--){ 75 // printf("[--> %lld]",query(1,dfn[2],dfn[2]+1)); 76 opt=read(); 77 if(opt==1){ 78 int x=read(),y=read(); 79 update(1,dfn[x],dfn[x],y); 80 } 81 else{ 82 if(opt==2){ 83 int x=read(),y=read(); 84 update(1,dfn[x],dfn[x]+siz[x]-1,y); 85 } 86 else{ 87 int x=read(),t=top[x]; LL ret=0; 88 while(x){ 89 ret+=query(1,dfn[t],dfn[x]); 90 x=fa[t]; t=top[x]; 91 // printf("[%d]\n",x); 92 } 93 printf("%lld\n",ret); 94 } 95 } 96 } 97 return 0; 98 }