Under [luogu] months' gross scene tree ": a good tree section title

The original title


 

Meaning of the questions:

To a tree, each side has the right side, four operations support

1. The k-th edge weight value is modified k

2. The right side of u to v is k nodes are covered

3. The right side of node u to v have increased k

4. Ask the right side of the maximum interval


 

Obviously tree section

Turn right and then right side point is the question of bare tree section

How right side turn right to the point


 

For a point u, v is her father

The u-> v is placed on the right side u do something right

Then the tree when the last section of this operation wave

1     if(a == b)
2         return;
3     if(dep[a] > dep[b])
4         std::swap(a, b);
5     SgCover(1, id[a] + 1, id[b], k);

This ensures that the right point of these two points of the LCA will not be counted (point to point in the right LCA is LCA-> fa [LCA], obviously can not count)


 

Another problem, lazytag segment tree

I maintain two lazy mark

It is a cov, is the coverage of the labeled lazy

One is add, marking an increase of lazy

As for the specific use or look at it ... very good understanding of the code


 

Code:

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<iostream>
  6 #include<algorithm>
  7 #define APART puts("----------------------")
  8 #define debug 1
  9 #define FILETEST 1
 10 #define inf 100010
 11 #define ll long long
 12 #define ha 998244353
 13 #define INF 0x7fffffff
 14 #define INF_T 9223372036854775807
 15 #define DEBUG printf("%s %d\n",__FUNCTION__,__LINE__)
 16 
 17 namespace chino{
 18 
 19 inline void setting(){
 20 #if FILETEST
 21     freopen("_test.in", "r", stdin);
 22     freopen("_test.me.out", "w", stdout);
 23 #endif
 24     return;
 25 }
 26 
 27 inline int read(){
 28     char c = getchar(), up = c; int num = 0;
 29     for(; c < '0' || c > '9'; up = c, c = getchar());
 30     for(; c >= '0' && c <= '9'; num = (num << 3) + (num << 1) + (c ^ '0'), c = getchar());
 31     return  up == '-' ? -num : num;
 32 }
 33 
 34 int n;
 35 int cntE, cntT;
 36 char s[inf];
 37 int mem[inf];
 38 int top[inf];
 39 int dep[inf];
 40 int son[inf];
 41 int fa[inf];
 42 int size[inf];
 43 int id[inf];
 44 int val[inf];
 45 int head[inf << 1];
 46 struct Edge{
 47     int to;
 48     int val;
 49     int next;
 50 }e[inf << 1];
 51 struct Tree{
 52     int l;
 53     int r;
 54     int max;
 55     int cov;
 56     int add;
 57 }t[inf << 2];
 58 std::pair <int, int> p[inf];
 59 #define lson(a) (a) << 1
 60 #define rson(a) (a) << 1 | 1
 61 
 62 inline void AddEdge(int from, int to, int val){
 63     ++cntE;
 64     e[cntE].to = to;
 65     e[cntE].val = val;
 66     e[cntE].next = head[from];
 67     head[from] = cntE;
 68     return; 
 69 }
 70 
 71 inline int getVal(int now){
 72     if(mem[now])
 73         return mem[now];
 74     for(int i = head[now]; i; i = e[i].next){
 75         if(fa[now] == e[i].to)
 76             return mem[now] = e[i].val;
 77     }
 78     return mem[now] = -INF;
 79 }
 80 
 81 void Dfs1(int now, int f, int depth){
 82     fa[now] = f;
 83     dep[now] = depth;
 84     size[now] = 1;
 85     int heavy = -INF;
 86     for(int i = head[now]; i; i = e[i].next){
 87         int to = e[i].to;
 88         if(to == f)
 89             continue;
 90         Dfs1(to, now, depth + 1);
 91         int y = size[to];
 92         size[now] += y;
 93         if(y > heavy){
 94             heavy = y;
 95             son[now] = to;
 96         }
 97     }
 98     return;
 99 }
100 
101 void Dfs2(int now, int point){
102     ++cntT;
103     top[now] = point;
104     id[now] = cntT;
105     val[cntT] = (now == 1 ? -INF : getVal(now));
106     if(son[now] == 0)
107         return;
108     Dfs2(son[now], point);
109     for(int i = head[now]; i; i = e[i].next){
110         int to = e[i].to;
111         if(to == fa[now] || to == son[now])
112             continue;
113         Dfs2(to, to);
114     }
115     return;
116 }
117 
118 using std::max;
119 
120 inline void updata(int now){
121     t[now].max = max (t[lson(now)].max , t[rson(now)].max);
122     return;
123 }
124 
125 inline void pushtag(int now){
126     if(t[now].cov != -INF){
127         t[lson(now)].max = t[now].cov;
128         t[rson(now)].max = t[now].cov;
129         t[lson(now)].cov = t[now].cov;
130         t[rson(now)].cov = t[now].cov;
131         t[lson(now)].add = 0;
132         t[rson(now)].add = 0;
133         t[now].cov = -INF;
134     }
135     if(t[now].add != 0){
136         t[lson(now)].max += t[now].add;
137         t[rson(now)].max += t[now].add;
138         t[lson(now)].add += t[now].add;
139         t[rson(now)].add += t[now].add;
140         t[now].add = 0;
141     }
142     return;
143 }
144 
145 void build(int now, int l, int r){
146     t[now].l = l;
147     t[now].r = r;
148     t[now].cov = -INF;
149     if(l == r){
150         t[now].max = val[l];
151         return;
152     }
153     int mid = (l + r) >> 1;
154     build(lson(now), l, mid);
155     build(rson(now), mid + 1, r);
156     updata(now);
157     return;
158 }
159 void SgCover(int now, int l, int r, int k){
160     if(t[now].l >= l && t[now].r <= r){
161         t[now].cov = t[now].max = k;
162         t[now].add = 0;
163         return;
164     }
165     pushtag(now);
166     int mid = (t[now].l + t[now].r) >> 1;
167     if(l <= mid)
168         SgCover(lson(now), l, r, k);
169     if(r > mid)
170         SgCover(rson(now), l, r, k);
171     updata(now);
172     return;
173 }
174 
175 void SgAdd(int now, int l, int r, int k){
176     if(t[now].l >= l && t[now].r <= r){
177         t[now].add += k;
178         t[now].max += k;
179         return;
180     }
181     pushtag(now);
182     int mid = (t[now].l + t[now].r) >> 1;
183     if(l <= mid)
184         SgAdd(lson(now), l, r, k);
185     if(r > mid)
186         SgAdd(rson(now), l, r, k);
187     updata(now);
188     return; 
189 }
190 
191 void SgChange(int now, int x, int k){
192     if(t[now].l > x || t[now].r < x)
193         return;
194     if(t[now].l == t[now].r){
195         t[now].max = k;
196         t[now].cov = -INF;
197         t[now].add = 0;
198         return;
199     }
200     pushtag(now);
201     int mid = (t[now].l + t[now].r) >> 1;
202     if(x <= mid)
203         SgChange(lson(now), x, k);
204     else 
205         SgChange(rson(now), x, k);
206     updata(now);
207     return;
208 }
209 
210 int SgQuery(int now, int l, int r){
211     if(t[now].l >= l && t[now].r <= r)
212         return t[now].max;
213     pushtag(now);
214     int mid = (t[now].l + t[now].r) >> 1;
215     int Max = -INF;
216     if(l <= mid)
217         Max = max (Max, SgQuery(lson(now), l, r));
218     if(r > mid)
219         Max = max (Max, SgQuery(rson(now), l, r));
220     return Max;
221 }
222 
223 inline void cover(int a, int b, int k){
224     while(top[a] != top[b]){
225         if(dep[top[a]] < dep[top[b]])
226             std::swap(a, b);
227         SgCover(1, id[top[a]], id[a], k);
228         a = fa[top[a]];
229     }
230     if(a == b)
231         return;
232     if(dep[a] > dep[b])
233         std::swap(a, b);
234     SgCover(1, id[a] + 1, id[b], k);
235     return;
236 } 
237 
238 inline void add(int a, int b, int k){
239     while(top[a] != top[b]){
240         if(dep[top[a]] < dep[top[b]])
241             std::swap(a, b);
242         SgAdd(1, id[top[a]], id[a], k);
243         a = fa[top[a]];
244     }
245     if(a == b)
246         return;
247     if(dep[a] > dep[b])
248         std::swap(a, b);
249     SgAdd(1, id[a] + 1, id[b], k);
250     return;
251 }
252 
253 inline int query(int a, int b){
254     int ans = -INF;
255     while(top[a] != top[b]){
256         if(dep[top[a]] < dep[top[b]])
257             std::swap(a, b);
258         ans = max (ans, SgQuery(1, id[top[a]], id[a]));
259         a = fa[top[a]];
260     }
261     if(a == b)
262         return ans;
263     if(dep[a] > dep[b])
264         std::swap(a, b);
265     ans = max (ans, SgQuery(1, id[a] + 1, id[b]));
266     return ans;
267 }
268 
269 inline int main(){
270     n = read();
271     for(int i = 1; i < n; i++){
272         p[i].first  = read();
273         p[i].second = read();
274         int w = read();
275         AddEdge(p[i].first, p[i].second, w);
276         AddEdge(p[i].second, p[i].first, w);
277     }
278     Dfs1(1, 0, 1);
279     Dfs2(1, 1);
280     build(1, 1, n);
281     while(true){
282         scanf("%s", s + 1);
283         if(s[1] == 'S')
284             break;
285         int a = read();
286         int b = read();
287         if(s[2] == 'a'){
288             int ans = query(a, b);
289             printf("%d\n", ans == -INF ? 0 : ans);
290         } else if(s[2] == 'o')
291             cover(a, b, read());
292         else if(s[2] == 'h'){
293             if(fa[p[a].first] == p[a].second)
294                 SgChange(1, id[p[a].first], b);
295             else 
296                 SgChange(1, id[p[a].second],b);
297         } else
298             add(a, b, read());
299     }
300     return 0;
301 }
302 
303 }//namespace chino
304 
305 signed main(){return chino::main();}

PS: This question is very difficult to write ah .. probably because I was too dishes .. written a long time ago ... and then hung up 0pts ... really do not want a transfer program 350 line ... later today reconstructed again ... but still rely on the beat debug code for several hours ... ah ... not force 

Guess you like

Origin www.cnblogs.com/chiarochinoful/p/problem-luogu-P4315.html