洛谷 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 }
View Code

 

posted @ 2018-07-31 18:42  Driver_Lao  阅读(148)  评论(0编辑  收藏  举报