数据结构--树链剖分详解

数据结构--树链剖分详解

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 
  6 using namespace std;
  7 
  8 const int maxn=4e6+10;
  9 struct node//±ß 
 10 {
 11     int to;
 12     int next;
 13 }way[maxn];
 14 struct tree//Ï߶ÎÊ÷ 
 15 {
 16     int l,r,ls,rs;
 17     int sum;
 18     int lazy;
 19 }tree[maxn];
 20 int head[maxn];
 21 int value[maxn];
 22 int top[maxn];
 23 int deep[maxn];
 24 int parents[maxn];
 25 int son[maxn];
 26 int size[maxn];
 27 int mod;
 28 int tot;
 29 int rt;
 30 int n,m,r;
 31 int jd[maxn];
 32 int dfsx[maxn];
 33 
 34 int add(int x,int y)
 35 {
 36     way[++tot].next=head[x];
 37     way[tot].to=y;
 38     head[x]=tot;
 39 }
 40 
 41 int dfs1(int x)
 42 {
 43     deep[x]=deep[parents[x]]+1;
 44     size[x]=1;
 45     for(int i=head[x];i;i=way[i].next)
 46     {
 47         int to=way[i].to;
 48         if(to!=parents[x])
 49         {
 50             parents[to]=x;
 51             dfs1(to);
 52             size[x]+=size[to];
 53             if(size[to]>size[son[x]])
 54             {
 55                 son[x]=to;
 56             }
 57         }
 58     }
 59     
 60 }
 61 
 62 int dfs2(int x,int t)
 63 {
 64     top[x]=t;
 65     dfsx[x]=++tot;
 66     jd[tot]=x;
 67     if(son[x])
 68     {
 69         dfs2(son[x],t);
 70     }
 71     for(int i=head[x];i;i=way[i].next)
 72     {
 73         int to=way[i].to;
 74         if(to!=parents[x]&&to!=son[x])
 75         {
 76             dfs2(to,to);
 77         }
 78     }
 79 }
 80 
 81 int len(int x)
 82 {
 83     return tree[x].r-tree[x].l+1;
 84 }
 85 
 86 inline int pushup(int x)
 87 {
 88     tree[x].sum=(tree[tree[x].ls].sum+tree[tree[x].rs].sum)%mod;
 89 }
 90 
 91 inline int pushdown(int x)
 92 {
 93     if(tree[x].lazy)
 94     {
 95         int ls=tree[x].ls;
 96         int rs=tree[x].rs;
 97         int lz=tree[x].lazy;
 98         tree[ls].lazy=(tree[ls].lazy+lz)%mod;
 99         tree[rs].lazy=(tree[rs].lazy+lz)%mod;
100         tree[ls].sum=(tree[ls].sum+lz*len(ls))%mod;
101         tree[rs].sum=(tree[rs].sum+lz*len(rs))%mod;
102         tree[x].lazy=0;
103     }
104 }
105 
106 void build(int l,int r,int x)
107 {
108     if(l==r)
109     {
110         tree[x].sum=value[jd[l]];
111         tree[x].l=tree[x].r=l;
112         return ;
113     }
114     int mid=(l+r)>>1;
115     tree[x].ls=tot++;
116     tree[x].rs=tot++;
117     build(l,mid,tree[x].ls);
118     build(mid+1,r,tree[x].rs);
119     tree[x].l=tree[tree[x].ls].l;
120     tree[x].r=tree[tree[x].rs].r;
121     pushup(x);
122 }
123 
124 void jia(int l,int r,int c,int x)
125 {
126     if(tree[x].l>=l&&tree[x].r<=r)
127     {
128         tree[x].lazy=(tree[x].lazy+c)%mod;
129         tree[x].sum=(tree[x].sum+c*len(x))%mod;
130         return ;
131     }
132     pushdown(x);
133     int mid=(tree[x].l+tree[x].r)>>1;
134     if(mid>=l)
135     {
136         jia(l,r,c,tree[x].ls);
137     }
138     if(mid<r)
139     {
140         jia(l,r,c,tree[x].rs);
141     }    
142     pushup(x);
143 }
144 
145 int he(int l,int r,int x)
146 {
147     if(tree[x].l>=l&&tree[x].r<=r)
148     {
149         return tree[x].sum;
150     }
151     pushdown(x);
152     int mid=(tree[x].l+tree[x].r)>>1;
153     int ans=0;
154     if(mid>=l)
155     {
156         ans+=he(l,r,tree[x].ls);
157     }
158     if(mid<r)
159     {
160         ans+=he(l,r,tree[x].rs);
161     }
162     return ans%mod;
163 }
164 
165 int ask(int x,int y)
166 {
167     int res=0;
168     while(top[x]!=top[y])
169     {
170         if(deep[top[x]]<deep[top[y]])
171         swap(x,y);
172         res=(res+he(dfsx[top[x]],dfsx[x],rt))%mod;
173         x=parents[top[x]];
174     }
175     if(dfsx[x]>dfsx[y])
176     swap(x,y);
177     res=(res+he(dfsx[x],dfsx[y],rt))%mod;
178     return res;
179 }
180 
181 int jias(int x,int y,int c)
182 {
183     while(top[x]!=top[y])
184     {
185         if(deep[top[x]]<deep[top[y]])
186         swap(x,y);
187         jia(dfsx[top[x]],dfsx[x],c,rt);
188         x=parents[top[x]];
189     }
190     if(dfsx[x]>dfsx[y])
191     swap(x,y);
192     jia(dfsx[x],dfsx[y],c,rt);
193 }
194 int main()
195 {
196     //freopen("ww.out","w",stdout);
197     scanf("%d %d %d %d",&n,&m,&r,&mod);
198     for(int i=1;i<=n;i++)
199     {
200         scanf("%d",&value[i]);
201     }
202     for(int i=1;i<=n-1;i++)
203     {
204         int x,y;
205         scanf("%d %d",&x,&y);
206         add(x,y);
207         add(y,x);;
208     }
209     tot=0;
210     dfs1(r);
211     dfs2(r,r);
212     tot=0;
213     build(1,n,rt=tot++);
214     for(int i=1;i<=m;i++)
215     {
216         int flag;
217         int x,y,z;
218         scanf("%d",&flag);
219         if(flag==1)
220         {
221             scanf("%d %d %d",&x,&y,&z);
222             jias(x,y,z);
223         }
224         else
225         if(flag==2)
226         {
227             
228             scanf("%d %d",&x,&y);
229             int ans=ask(x,y);
230             printf("%d\n",ans);
231         }
232         else
233         if(flag==3)
234         {
235             scanf("%d %d",&x,&y);
236             jia(dfsx[x],dfsx[x]+size[x]-1,y,rt);
237         }
238         else
239         if(flag==4)
240         {
241             scanf("%d",&x);
242             int ans=he(dfsx[x],dfsx[x]+size[x]-1,rt);
243             printf("%d\n",ans);
244         }
245     }
246     
247     return 0;
248 }

猜你喜欢

转载自www.cnblogs.com/2529102757ab/p/10732188.html