Fork me on 
Catalogue

我自问酒不问仙,半世逍遥半世癫,我自问心不问佛,半世情愁半世痴。 ​​​​

汉孤臣の树链剖分模板



  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <vector>
  7 #include <queue>
  8 #include <stack>
  9 using namespace std;
 10 const int maxn=200000+50;
 11 
 12 int n,m,ans,tot,cnt,h[maxn],g[maxn];
 13 
 14 struct node
 15 {
 16     int b,next;
 17 };
 18 node table[maxn];
 19 
 20 struct nodee
 21 {
 22     vector<int> son;
 23     int s,size,en,id,d,weight,w,f,top;
 24 };
 25 nodee tree[maxn];
 26 
 27 struct nodeee
 28 {
 29     int l,r;
 30     long long w,add;
 31 };
 32 nodeee treex[maxn<<2];
 33 
 34 void add(int x,int y)
 35 {
 36     table[++cnt].b=y;
 37     table[cnt].next=h[x];
 38     h[x]=cnt;
 39 }
 40 
 41 void dfs1(int x,int fa)
 42 {
 43     tree[x].weight=tree[x].size=1;
 44     tree[x].d=tree[fa].d+1;
 45     tree[x].f=fa;
 46     for (int i=h[x]; i; i=table[i].next)
 47     {
 48         int t=table[i].b;
 49         if (t!=fa)
 50         {
 51             tree[x].son.push_back(t);
 52             dfs1(t,x);
 53             if (tree[x].weight<tree[t].size+1)
 54             {
 55                 tree[x].s=t;
 56                 tree[x].weight=tree[t].size+1;
 57             }
 58             tree[x].size+=tree[t].size;;
 59         }
 60     }
 61 }
 62 
 63 void dfs2(int x,int fa)
 64 {
 65     tree[x].id=++cnt;
 66     g[cnt]=x;
 67     tree[x].top=fa;
 68     if (tree[x].s)
 69         dfs2(tree[x].s,fa);
 70     for (int i=0; i<tree[x].son.size(); ++i)
 71     if (tree[x].son[i]!=tree[x].s)
 72     {
 73         dfs2(tree[x].son[i],tree[x].son[i]);
 74     }
 75     tree[x].en=cnt;
 76 }
 77 
 78 void pushup(int tr)
 79 {
 80     treex[tr].w=treex[tr<<1].w+treex[tr<<1|1].w;
 81 }
 82 
 83 void pushdown(int lsum,int rsum,int tr)
 84 {
 85     if (!treex[tr].add)
 86     {
 87         return;
 88     }
 89     treex[tr<<1].w+=(long long) (lsum)*treex[tr].add;
 90     treex[tr<<1|1].w+=(long long) (rsum)*treex[tr].add;
 91     treex[tr<<1].add+=treex[tr].add;
 92     treex[tr<<1|1].add+=treex[tr].add;
 93     treex[tr].add=0;
 94 }
 95 
 96 void build(int l,int r,int tr)
 97 {
 98     treex[tr].l=l;
 99     treex[tr].r=r;
100     if (l==r)
101     {
102         treex[tr].w=tree[g[l]].w;
103         return;
104     }
105     int mid=(l+r)>>1;
106     build(l,mid,tr<<1);
107     build(mid+1,r,tr<<1|1);
108     pushup(tr);
109 }
110 
111 void update(int l,int r,int tr,int ql,int qr,int qw)
112 {
113     if (l>=ql && r<=qr)
114     {
115         treex[tr].add+=qw;
116         treex[tr].w+=(long long)qw*(long long)(r-l+1);
117         return;
118     }
119     int mid=(l+r)>>1;
120     pushdown(mid-l+1,r-mid,tr);
121     if (mid>=ql)
122         update(l,mid,tr<<1,ql,qr,qw);
123     if (mid<qr)
124         update(mid+1,r,tr<<1|1,ql,qr,qw);
125     pushup(tr);
126     return;
127 }
128 
129 long long query(int l,int r,int tr,int ql,int qr)
130 {
131     if (l>=ql && r<=qr)
132     {
133         return treex[tr].w;
134     }
135     int mid=(l+r)>>1;
136     pushdown(mid-l+1,r-mid,tr);
137     long long tot=0;
138     if (mid>=ql)
139     tot+=query(l,mid,tr<<1,ql,qr);
140     if (mid<qr)
141     tot+=query(mid+1,r,tr<<1|1,ql,qr);
142     return tot;
143 }
144 
145 void ask(int q)
146 {
147     long long tot=0;
148     while (tree[q].top!=1)
149     {
150         tot+=query(1,n,1,tree[tree[q].top].id,tree[q].id);
151         q=tree[tree[q].top].f;
152     }
153     tot+=query(1,n,1,tree[1].id,tree[q].id);
154     printf("%lld\n",tot);
155 }
156 
157 int main()
158 {
159     scanf("%d%d",&n,&m);
160     for (int i=1; i<=n; ++i)
161         scanf("%d",&tree[i].w);
162     for (int i=1,q1,q2; i<n; ++i)
163     {
164         scanf("%d%d",&q1,&q2);
165         add(q1,q2);
166         add(q2,q1);
167     }
168     dfs1(1,1);
169     cnt=0;
170     dfs2(1,1);
171     build(1,n,1);
172     for (int i=1,q1,q2,q3; i<=m; ++i)
173     {
174         scanf("%d%d",&q1,&q2);
175         if (q1==1)
176         {
177             scanf("%d",&q3);
178             update(1,n,1,tree[q2].id,tree[q2].id,q3);
179         }
180         if (q1==2)
181         {
182             scanf("%d",&q3);
183             update(1,n,1,tree[q2].id,tree[q2].en,q3);
184         }
185         if (q1==3)
186             ask(q2);
187     }
188     return 0;
189 }

 

 

模板题http://private.vjudge.net/problem/LibreOJ-10138

posted @ 2020-11-05 16:57  汉孤臣  阅读(86)  评论(0)    收藏  举报
Live2D