BZOJ 4034 "operator tree" (DFS segment tree sequence +)

 

Portal

 

• the meaning of problems

  There are a number of points N of the tree is the root to the point, and the right side has a tree points.

  Then there are M operations, divided into three types:

    Action 1: the right point of a node x increases a.
    Operation 2: The subtree rooted at some node x of weights of all points are point increases a.
    Operation 3: interrogation points right path to a node x to the root node and all.
  3 corresponds to the output operation of the answer;

•answer

  If the tree structure can be converted into a chain structure, then, the operation 2 can be used to maintain the segment tree;

  $1,2,4,4,5,5,2,3,3,1$

  Defined $ s, e $ are recorded position of each node in the sequence and position of the first occurrence of the last occurrence;

  So, the position of the first occurrence of the right is positive, the position of the last occurrence of the right value is negative;

  In this case, it can be maintained through the tree line;

  Operation 1 corresponds to a single point in the segment tree update operations;

  2 corresponds to the operation section in the segment tree updating operation;

  3 is the operating range query;

•Code

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define ls(x) (x<<1)
  5 #define rs(x) (x<<1|1)
  6 #define mem(a,b) memset(a,b,sizeof(a))
  7 const int maxn=1e5+50;
  8 
  9 int n,m;
 10 int a[maxn];
 11 int num;
 12 int head[maxn];
 13 struct Edge
 14 {
 15     intto;
 16      int Next;
 . 17 } G [MAXN << . 1 ];
 18 is  void addEdge ( int U, int V)
 . 19  {
 20 is      G [NUM] = {V, head [U]};
 21 is      head [U] = NUM ++ ;
 22 is  }
 23 is  struct Seg
 24  {
 25      int L, R & lt;
 26 is      LL the lazy;
 27      LL SUM;
 28      int X; /// in the direction of the leaf node number 
29      int Y; /// number of the root node in the direction 
30     int MID () { return L + ((rl is an) >> . 1 );}
 31 is      void the Set (LL Val)
 32      {
 33 is          /// If [l, r] of each node have increased interval Val
 34 is          /// less, [l, r] interval along the x direction leaf nodes increases Val +
 35          /// [l, r] interval in the y direction is the root node increases -Val 
36          the lazy + = Val;
 37 [          SUM = 1LL + * (XY) * Val;
 38 is      }
 39 } SEG [<< MAXN . 3 ];
 40  int CNT;
 41 is  int S [MAXN];
 42 is  int E [MAXN];
 43 is  int vs[maxn<<1];
 44 bool g[maxn<<1];
 45 
 46 void DFS(int u,int f)
 47 {
 48     vs[++cnt]=u;
 49     s[u]=cnt;
 50     g[cnt]=1;
 51     for(int i=head[u];~i;i=G[i].next)
 52     {
 53         int v=G[i].to;
 54         if(v != f)
 55             DFS(v,u);
 56     }
57      vs [++ CNT] = l;
58      e [u] = CNT;
59      g [CNT] = 0 ;
60  }
 61  void pushUp ( int gum)
 62  {
 63      seg [gum] .x = seg [ls (gum)]. X + seg [rs (gum)]. X;
64      seg [gum] .y = seg [ls (gum)]. Y + seg [rs (gum)]. Y;
65      seg [gum] .sum = seg [ls (gum)]. Sum + seg [rs (gum)]. Sum;
66  }
 67  void pushDown ( int gum)
 68  {
 69      ll & lazy = seg [gum] .lazy;
70     if(!lazy)
 71         return ;
 72 
 73     seg[ls(pos)].Set(lazy);
 74     seg[rs(pos)].Set(lazy);
 75 
 76     lazy=0;
 77 }
 78 void build(int l,int r,int pos)
 79 {
 80     seg[pos]={l,r,0,0,0,0};
 81 
 82     if(l == r)
 83     {
 84         if(g[l])
 85         {
 86             seg[pos].x++;
 87             seg[pos].sum=a[vs[l]];
 88         }
 89         else
 90         {
 91             seg[pos].y++;
 92             seg[pos].sum=-a[vs[l]];
 93         }
 94 
 95         return ;
 96     }
 97 
 98     int mid=seg[pos].mid();
 99     build(l,mid,ls(pos));
100     build(mid+1,r,rs(pos));
101 
102     pushUp(pos);
103 }
104 void update(int pos,int l,int r,int x)
105 {
106     if(seg[pos].l == l && seg[pos].r == r)
107     {
108         seg[pos].Set(x);
109         return ;
110     }
111     pushDown(pos);
112 
113     int mid=seg[pos].mid();
114     if(r <= mid)
115         update(ls(pos),l,r,x);
116     else if(l > mid)
117         update(rs(pos),l,r,x);
118     else
119     {
120         update(ls(pos),l,mid,x);
121         update(rs(pos),mid+1,r,x);
122     }
123     pushUp(pos);
124 }
125 ll query(int pos,int l,int r)
126 {
127     if(seg[pos].l == l && seg[pos].r == r)
128         return seg[pos].sum;
129     pushDown(pos);
130 
131     int mid=seg[pos].mid();
132     if(r <= mid)
133         return query(ls(pos),l,r);
134     else if(l > mid)
135         return query(rs(pos),l,r);
136     else
137         return query(ls(pos),l,mid)+query(rs(pos),mid+1,r);
138 }
139 void Solve()
140 {
141     cnt=0;
142     DFS(1,1);
143     build(1,cnt,1);
144 
145     while(m--)
146     {
147         int op;
148         scanf("%d",&op);
149         if(op == 1)
150         {
151             int u,x;
152             scanf("%d%d",&u,&x);
153             update(1,s[u],s[u],x);
154             update(1,e[u],e[u],x);
155         }
156         else if(op == 2)
157         {
158             int u,x;
159             scanf("%d%d",&u,&x);
160             update(1,s[u],e[u],x);
161         }
162         else
163         {
164             int u;
165             scanf("%d",&u);
166             printf("%lld\n",query(1,s[1],s[u]));
167         }
168     }
169 }
170 void Init()
171 {
172     num=0;
173     mem(head,-1);
174 }
175 int main()
176 {
177 //    freopen("C:\\Users\\hyacinthLJP\\Desktop\\C++WorkSpace\\in&&out\\contest","r",stdin);
178     scanf("%d%d",&n,&m);
179     for(int i=1;i <= n;++i)
180         scanf("%d",a+i);
181 
182     Init();
183     for(int i=1;i < n;++i)
184     {
185         int u,v;
186         scanf("%d%d",&u,&v);
187         addEdge(u,v);
188         addEdge(v,u);
189     }
190     Solve();
191 
192     return 0;
193 }
View Code

• deformation

  This problem may also be changed to solve the operation 3 $ u, and the node between the weights v $ path;

  Just add a code to solve the $ LCA $ to the basis of the original;

Guess you like

Origin www.cnblogs.com/violet-acmer/p/11783072.html