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