Split chain tree template

  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <string>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <math.h>
  9 #include <map>
 10 
 11 #define LL long long
 12 using namespace std;
 13 const int maxn = 2e5 + 10;
 14 
 15 struct Edge{
 16     int to,next;
 17 }edge[maxn];
 18 
 19 int tot,head[maxn];
 20 
 21 void add_edge(int u,int v){
 22     edge[tot] = Edge{v,head[u]};
 23     head[u] = tot++;
 24     edge[tot] = Edge{u,head[v]};
 25     head[v] = tot++;
 26 }
 27 
 28 int mod;
 29 int v[maxn]; // 结点权值
 30 int fa[maxn]; // 父亲
 31 intDEP [MAXN]; // depth 
32  int SIZ [MAXN]; // Size 
33 is  int Son [MAXN]; // weight son
 34 is  
35  // first pass depth can be dfs, father, size, weight son 
36  void DFS1 ( int u, int F) { // u is the current node, f u is the father of 
37 [      FA [u] = F;
 38 is      DEP [u] = DEP [F] + . 1 ;
 39      SIZ [u] = . 1 ;
 40      int MAXSIZE = - . 1 ;   // Analyzing a temporary variable is not a son weight 
41 is      for( Int I = head [U]; ~ I; I = Edge [I] .next) {
 42 is          int V = Edge [I] .to;
 43 is          IF (V == F)    // if it is not the father affirmative 
44              Continue ;
 45          DFS1 (V, U);
 46 is          SIZ [U] + = SIZ [V];
 47          IF (SIZ [V]> MAXSIZE) {
 48              MAXSIZE = SIZ [V];
 49              Son [U] = V;   / / U son is heavy V 
50          }
 51 is      }
 52 is  }
 53 is  
54 is  int Tim; //Timestamp counter 
55  int DFN [MAXN]; // stamp 
56 is  int Top [MAXN]; // the top of the heavy chain 
57 is  int W [MAXN]; // node weights dfs sequence 
58  
59  void DFS2 ( int U, int T) { // U is the current node, t is the current node is the head of the heavy chain 
60      DFN [U] = ++ Tim;
 61 is      Top [U] = T;
 62 is      W [Tim] = V [U] ;
 63      IF (! son [U])   // If heavy son does not exist, then it is a leaf node, exit 
64-          return ;
 65     DFS2 (Son [U], T);
 66      for ( int I = head [U]; ~ I; I = Edge [I] .next) {
 67          int V = Edge [I] .to;
 68          IF (V = FA = [U] || v == son [U])    // up traversal certainly not, because the front dfs2 has traversed a heavy son here so did not need the 
69              the Continue ;
 70          dfs2 (v, v) ;    // this time the son is certainly light 
71 is      }
 72  }
 73 is  
74  struct segment_tree {
 75      int L, R & lt, Val;
 76      int the lazy;
 77 } Tree [* MAXN . 4 ];
 78 
 79 void pushup(int nod){
 80     tree[nod].val = (tree[nod<<1].val + tree[(nod<<1)+1].val) % mod;
 81 }
 82 
 83 void pushdown(int nod){
 84     tree[nod<<1].lazy += tree[nod].lazy;
 85     tree[(nod<<1)+1].lazy += tree[nod].lazy;
 86     tree[nod<<1].val += (tree[nod<<1].r-tree[nod<<1].l + 1) * tree[nod].lazy % mod;
 87     tree[(nod<<1)+1].val += (tree[(nod<<1)+1].r-tree[(nod<<1)+1].l+1) * tree[nod].lazy % mod;
 88     tree[nod].lazy = 0;
 89 }
 90 
 91 void build(int l,int r,int nod=1){
 92     tree[nod].l = l;
 93     tree[nod].r = r;
 94     if (l == r){
 95         tree[nod].lazy = 0;
 96         tree[nod].val = w[l] % mod;
 97         return ;
 98     }
 99     int mid = (l+r)>>1;
100     build(l,mid,nod<<1);
101     build(mid+1,r,(nod<<1)+1);
102     pushup(nod);
103 }
104 
105 void modify(int x,int y,int z,int k=1){
106     int l = tree[k].l, r = tree[k].r;
107     if (x<= l && y>=r){
108         tree[k].lazy += z;
109         tree[k].val += (r-l+1) * z;
110         tree[k].val %= mod;
111         return ;
112     }
113     if (tree[k].lazy)
114         pushdown(k);
115     int mid = (l+r)>>1;
116     if (x<=mid){
117         modify(x,y,z,k<<1);
118     }
119     if (y>mid){
120         modify(x,y,z,(k<<1)+1);
121     }
122     pushup(k);
123 }
124 
125 int query(int x,int y,int k=1){
126     int l = tree[k].l,r = tree[k].r;
127     if (x<=l && y>=r){
128         return tree[k].val;
129     }
130     if (tree[k].lazy){
131         pushdown(k);
132     }
133     int sum = 0,mid = (l+r)>>1;
134     if (x <= mid){
135         sum += query(x,y,k<<1);
136     }
137     if (y > mid){
138         sum += query(x,y,(k<<1)+1);
139     }
140     return sum % mod;
141 }
142 
143 void mchain(int x,int y,int Z) {   // node x-> node on the shortest path to all nodes y plus Z 
144      Z% = MOD;
 145      the while ! (Top [X] = Top [y]) {
 146          IF (DEP [Top [ X]] < DEP [Top [Y]])
 147              the swap (X, Y);
 148          Modify (DFN [Top [X]], DFN [X], Z);
 149          X = FA [Top [X]];
 150      }
 151      IF (DEP [X]> DEP [Y])
 152          the swap (X, Y);
 153      Modify (DFN [X], DFN [Y], Z);
 154  }
 155  
156  int QChain ( int X, inty) {   // query to x values of all nodes in the shortest path and the y nodes 
157      int RET = 0 ;
 158      the while ! (Top [x] = Top [y]) {
 159          IF (DEP [Top [x] ] < DEP [Top [Y]])
 160.              the swap (X, Y);
 161          RET + = Query (DFN [Top [X]], DFN [X]);
 162          X = FA [Top [X]];
 163      }
 164 is      IF (DEP [X]> DEP [Y])
 165          the swap (X, Y);
 166      RET + = Query (DFN [X], DFN [Y]);
 167 is      return RET% MOD;
 168  }
169  
170.  void MSON ( int x, int Z) { // for all nodes within the x value is a root node of the subtree are coupled Z 
171 is      Modify (DFN [x], DFN [x] + SIZ [x] - . 1 , Z);   // must be continuous 
172  }
 173  
174  int qson ( int x) {   // for all nodes within the x value as the root node of the subtree and 
175      return Query (DFN [x], DFN [x] + SIZ [X] - . 1 );
 176  }
 177  
178  
179  int main () {
 180 [      Memset (head, - . 1 , the sizeof (head));
 181     int n,m,r;
182     scanf("%d%d%d%d",&n,&m,&r,&mod);
183     for (int i=1;i<=n;i++){
184         scanf("%d",&v[i]);
185     }
186     for (int i=1;i<n;i++){
187         int u,v;
188         scanf("%d%d",&u,&v);
189         add_edge(u,v);
190     }
191     dfs1(r,r);
192     dfs2(r,r);
193     build(1,n);
194     while (m--){
195         int opt,x,y,z;
196         scanf("%d",&opt);
197         switch(opt){
198             case 1:
199                 scanf("%d%d%d",&x,&y,&z);
200                 mchain(x,y,z);
201                 break;
202             case 2:
203                 scanf("%d%d",&x,&y);
204                 printf("%d\n",qchain(x,y));
205                 break;
206             case 3:
207                 scanf("%d%d",&x,&z);
208                 mson(x,z);
209                 break;
210             case 4:
211                 scanf("%d",&x);
212                 printf("%d\n",qson(x));
213                 break;
214         }
215     }
216     return 0;
217 }

 

Guess you like

Origin www.cnblogs.com/-Ackerman/p/11391343.html