Question:
A tree is provided with four operations:
1. If X and Y are not in the same tree, they are connected to XY.
2. If X and Y are in the same tree and X! = Y, then convert X to the root of the tree and separate y from Y's father.
3. If X and Y are in the same tree, then all vertex weights from X to Y + W
4. If X and Y are in the same tree, the maximum values from X to Y are output.
Dynamic Tree entry question:
# Include <iostream> # include <cstdio> using namespace STD; const int maxn = 333333; struct node {int Val, Max, Inc; bool Rev; node * par, * Ch [2];} dt [maxn], * nil = DT; struct linkcuttree {inline void _ Inc (node * X, int Inc) {If (x = nil) return; X-> Inc + = Inc, X-> Val + = Inc, X-> MAX + = Inc;} inline void clear (node * const X) {If (x = nil) return; If (X-> Inc) {_ Inc (X-> CH [0], X-> Inc ); _ Inc (X-> CH [1], X-> Inc); X-> Inc = 0;} If (X-> rev) {swap (X-> CH [0], x-> CH [1]); X-> CH [0]-> rev ^ = 1; X-> CH [1]-> rev ^ = 1; x-> REV = 0 ;}} inline void Update (node * X) {clear (x); clear (X-> CH [0]), clear (X-> CH [1]); X-> max = max (X-> Val, max (X-> CH [0]-> MAX, x-> CH [1]-> MAX);} void rotate (node * X) {node * P = x-> par, * g = p-> par; clear (P), clear (x); int c = p-> CH [0] = x; // 0 left-hand, 1 right-handed p-> CH [C ^ 1] = x-> CH [c]; If (X-> CH [c]! = Nil) x-> CH [c]-> par = P; X-> par = g; If (G-> CH [0] = P) g-> CH [0] = x; else if (G-> CH [1] = P) g-> CH [1] = X; x-> CH [c] = P; P-> par = x; Update (p);} void splay (node * X) {If (x = nil) return; while (X-> par! = Nil & (X-> par-> CH [0] = x | X-> par-> CH [1] = x )) {If (X-> par! = Nil) rotate (x); else {node * P = x-> par, * g = p-> par; if (G-> CH [1] = P) = (p-> CH [1] = x) rotate (P), rotate (X ); else rotate (x), rotate (x) ;}} Update (x) ;}node * access (node * u) {node * V = nil; For (; u! = Nil; u = u-> par) {splay (U); U-> CH [1] = V; Update (V = U);} return V ;} node * getroot (node * X) {for (x = access (x); clear (x), x-> CH [0]! = Nil; X = x-> CH [0]); Return X;} inline void Evert (node * X) {access (x)-> rev ^ = 1; splay (x);} inline void Link (node * X, node * Y) {Evert (x); X-> par = y; Access (x );} inline void cut (node * X, node * Y) {Evert (x); Access (y); splay (y ); y-> CH [0]-> par = nil; y-> CH [0] = nil; Update (y);} inline int query (node * X, node * Y) {Evert (x); Access (Y), splay (y); Return y-> MAX;} inline void Modi FY (node * X, node * y, int W) {Evert (x); Access (Y), splay (y); _ Inc (Y, W );}} LCT; int n, m; int main () {While (scanf ("% d", & N )! = EOF) {for (INT I = 0; I <= N; I ++) {dt [I]. val = dt [I]. max = dt [I]. INC = 0; dt [I]. par = dt [I]. ch [0] = dt [I]. ch [1] = nil; dt [I]. REV = 0 ;}for (INT I = 1, x, y; I <n; ++ I) {scanf ("% d", & X, & Y); LCT. link (DT + X, DT + Y) ;}for (INT I = 1, x; I <= N; ++ I) {scanf ("% d ", & X); node * TEM = DT + I; LCT. splay (TEM); TEM-> val = tem-> max = x; LCT. update (TEM);} scanf ("% d", & M); For (INT I = 0, OP, X, y, z; I <m; ++ I) {scanf ("% d", & OP, & X, & Y ); switch (OP) {Case 1: If (LCT. getroot (DT + x) = LCT. getroot (DT + y) printf ("-1 \ n"); else LCT. link (DT + X, DT + Y); break; Case 2: If (x = Y | LCT. getroot (DT + x )! = LCT. getroot (DT + y) printf ("-1 \ n"); else LCT. cut (DT + X, DT + Y); break; Case 3: scanf ("% d", & Z); If (LCT. getroot (DT + Y )! = LCT. getroot (DT + Z) printf ("-1 \ n"); else LCT. modify (DT + Y, DT + Z, x); break; Case 4: If (LCT. getroot (DT + x )! = LCT. getroot (DT + y) printf ("-1 \ n"); else printf ("% d \ n", LCT. query (DT + X, DT + y); break ;}} putchar (10 );}}
View code
HDU 4010. query on the trees solution report