Hdu_3966
For the question of tree link splitting, we recommend a blog that is easy to understand: http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html.
# Include <stdio. h> # Include < String . H> # Define Maxd 50010 # Define Maxm 100010 Int N, m, Q, first [maxd], E, next [maxm], V [maxm]; Int Fa [maxd], DEP [maxd], size [maxd], son [maxd], top [maxd], W [maxd], CNT; Int A [maxd], add [ 4 * Maxd], Q [maxd]; Void Swap ( Int & X, Int & Y ){ Int T; t = X, x = Y, y = T ;} Void Add ( Int X, Int Y) {v [E] =Y; next [E] = First [X], first [x] = e ++ ;} Void Pushdown ( Int Cur ){ If (Add [cur]) {Add [cur < 1 ] + = Add [cur], add [cur < 1 | 1 ] + = Add [cur]; add [cur] = 0 ;}} Void Prepare (){ Int I, j, X, rear = 0 ; Q [rear ++] = 1 ; Fa [ 1 ] = 0 , DEP [ 1 ] = 1 ; For (I = 0 ; I <rear; I ++) {X = Q [I]; For (J = first [X]; J! =- 1 ; J = Next [J]) If (V [J]! = Fa [x]) {Fa [V [J] = X, DEP [V [J] = Dep [x] + 1 ; Q [rear ++] = V [J] ;}} size [ 0 ] = 0 ; For (I = rear- 1 ; I> = 0 ; I -- ) {X = Q [I]; Size [x] = 1 , Son [x] = 0 ; For (J = first [X]; J! =- 1 ; J = Next [J]) If (V [J]! =Fa [x]) {size [x] + = Size [V [J]; If (Size [V [J]> Size [son [x]) Son [x] = V [J] ;}} CNT = 0 ; Memset (top, 0 , Sizeof (Top )); For (I = 0 ; I <rear; I ++) {X = Q [I]; If (Top [x] = 0 ){ For (J = x; J! = 0 ; J = Son [J]) Top [J] = X, W [J] = ++ CNT ;}}} Void Refresh ( Int Cur, Int X, Int Y,Int S, Int T, Int V ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X> = S & Y <= T) {Add [cur] + = V; Return ;} Pushdown (cur ); If (Mid> = S) Refresh (LS, X, mid, S, T, V ); If (Mid + 1 <= T) Refresh (RS, mid + 1 , Y, S, T, V );} Void Init (){ Int I, X, Y; For (I =1 ; I <= N; I ++ ) Scanf ( " % D " ,& A [I]); e = 0 ; Memset (first, - 1 , Sizeof (First )); For (I = 0 ; I <m; I ++ ) {Scanf ( " % D " , & X ,& Y); add (x, y), add (Y, x);} prepare (); memset (add, 0 , Sizeof (ADD )); For (I = 1 ; I <= N; I ++ ) Refresh ( 1 , 1 , N, W [I], W [I], a [I]);} Int Search (Int Cur, Int X, Int Y, Int K ){ Int Mid = (x + y)> 1 , Ls = cur < 1 , RS = cur < 1 | 1 ; If (X = Y) Return Add [cur]; Pushdown (cur ); If (K <= Mid) Return Search (LS, X, mid, k ); Else Return Search (RS, Mid + 1 , Y, k );} Void Deal ( Int X, Int Y, Int Z ){ Int FX = top [X], FY = Top [y]; While (FX! = FY ){ If (DEP [FX]> Dep [FY]) Swap (FX, FY), swap (x, y); refresh ( 1 , 1 , N, W [FY], W [Y], Z); y = Fa [FY], FY = Top [y];} If (DEP [x]> Dep [y]) Swap (x, y); refresh ( 1 , 1 , N, W [X], W [Y], Z );} Void Solve (){ Int I, x, y, z; Char OP [ 5 ]; For (I = 0 ; I <q; I ++ ) {Scanf ( " % S % d " , Op ,& X ); If (OP [ 0 ] = ' Q ' ) Printf ( " % D \ n " , Search ( 1 , 1 , N, W [x]); Else {Scanf ( " % D " , & Y ,& Z ); If (OP [ 0 ] = ' I ' ) Deal (x, y, z ); Else Deal (x, y, - Z );}}} Int Main (){ While (Scanf ( " % D " , & N, & M, & Q) = 3 ) {Init (); solve ();} Return 0 ;}