Poj_3237
You can use link-cut-tree or tree link splitting. To handle the negate operation, two labels, Max and Min, can be used out of the lazy tag, set max to-min and min to-max.
# Include <stdio. h> # Include < String . H> # Define Maxd 100010 # Define Maxm 200010 # Define INF 0x7fffffff Int N, Q [maxd], first [maxd], E, next [maxm], V [maxm], W [maxm], DEP [maxd]; Struct Edge { Int X, Y, Z;} edge [maxd]; Struct Splay { Int PRE, ls, RS, neg, key, Max, min; Bool Root; Void Update (); Void Pushdown (); Void Zig ( Int ); Void Zag (Int ); Void Splay ( Int ); Void RENEW () {Root = True ; Pre = Ls = rs = 0 ; Neg = 0 ;}} SP [maxd]; Int Max ( Int X,Int Y ){ Return X> Y? X: Y ;} Int Min ( Int X, Int Y ){ Return X <Y? X: Y ;} Void Splay: Update () {max = Max (max (SP [ls]. Max, SP [RS]. max), key); min =Min (min (SP [ls]. Min, SP [RS]. min), key );} Void Makeneg ( Int Cur ){ If (Cur! = 0 ) {SP [cur]. neg ^ = 1 , SP [cur]. Key =- SP [cur]. Key; Int T = SP [cur]. Max; SP [cur]. Max =-SP [cur]. Min, SP [cur]. min =- T ;}} Void Splay: Pushdown (){ If (NEG) {makeneg (LS), makeneg (RS); neg = 0 ;}} Void Splay: Zig ( Int X ){ Int Y = RS, fa = Pre; Pushdown (), SP [Y]. Pushdown (); RS = Sp [Y]. ls, SP [RS]. Pre = X; SP [Y]. ls = X, pre = Y; SP [Y]. Pre =Fa; If (Root) Root = False , SP [Y]. Root = True ; Else SP [fa]. RS = X? SP [fa]. rs = Y: SP [fa]. ls = Y; Update ();} Void Splay: zag ( Int X ){ Int Y = ls, fa =Pre; Pushdown (), SP [Y]. Pushdown (); LS = Sp [Y]. RS, SP [ls]. Pre = X; SP [Y]. RS = X, pre = Y; SP [Y]. Pre = Fa; If (Root) Root = False , SP [Y]. Root = True ; Else SP [fa]. RS = X? SP [fa]. rs = Y: SP [fa]. ls = Y; Update ();} Void Splay: splay ( Int X ){ Int Y, Z; For (Pushdown ();! Root;) {Y = Pre; If (SP [Y]. Root) SP [Y]. RS = X? SP [Y]. Zig (y): SP [Y]. Zag (y ); Else {Z =SP [Y]. Pre; If (SP [Z]. rs = Y ){ If (SP [Y]. rs = X) SP [Z]. Zig (z), SP [Y]. Zig (y ); Else SP [Y]. Zag (Y), SP [Z]. Zig (z );} Else { If (SP [Y]. ls = X) SP [Z]. Zag (z), SP [Y]. Zag (y ); Else SP [Y]. Zig (Y), SP [Z]. Zag (z) ;}} Update ();} Void Add ( Int X, Int Y, Int Z) {v [E] = Y, W [e] = Z; next [E] = First [X], first [x] = e ++ ;} Void Prepare (){ Int I, j, X, rear = 0 ; SP [ 0 ]. Max =-INF, SP [ 0 ]. Min = INF; Q [rear ++] = 1 ; SP [ 1 ]. RENEW (), DEP [ 1 ] = 1 ; For (I = 0 ; I <rear; I ++ ) {X = Q [I]; For (J = first [X]; J! =- 1 ; J = Next [J]) If (V [J]! = SP [X]. PRE) {SP [V [J]. RENEW (), SP [V [J]. Pre = X, DEP [V [J] = Dep [x] + 1 ; SP [V [J]. Key = Sp [V [J]. max = Sp [V [J]. min = W [J]; Q [rear ++] = V [J] ;}} Void Swap ( Int & X, Int &Y ){ Int T; t = X, x = Y, y = T ;} Void Init (){ Int I; memset (first, - 1 , Sizeof (First); e = 0 ; Scanf ( " % D " ,& N ); For (I = 1 ; I <n; I ++ ) {Scanf ( " % D " , & Edge [I]. X, & edge [I]. Y ,& Edge [I]. z); add (edge [I]. x, edge [I]. y, edge [I]. z), add (edge [I]. y, edge [I]. x, edge [I]. z);} prepare (); For (I = 1 ; I <n; I ++ ) If (DEP [edge [I]. x]>Dep [edge [I]. Y]) Swap (edge [I]. X, edge [I]. Y );} Void Access ( Int X ){ Int FX; For (FX = x, x = 0 ; FX! = 0 ; X = FX, FX = SP [X]. PRE) {SP [FX]. splay (FX); SP [Sp [FX]. RS]. Root = True ; SP [FX]. RS = X, SP [X]. Root = False ; SP [FX]. Update ();}} Void Change ( Int X, Int Y) {SP [X]. splay (x); SP [X]. Key = Y; SP [X]. Update ();} Void Negate ( Int X, Int Y ){ Int FY; Access (X ); For (FY = Y, y = 0 ; FY! = 0 ; Y = fy, FY = SP [Y]. PRE) {SP [FY]. splay (FY ); If (SP [FY]. Pre = 0 ) Makeneg (SP [FY]. RS), makeneg (y); SP [Sp [FY]. RS]. Root = True ; SP [FY]. RS = Y, SP [Y]. Root = False ; SP [FY]. Update ();}} Void Query ( Int X, Int Y ){ Int FY; Access (X ); For (FY = Y, y = 0 ; FY! = 0 ; Y = fy, FY = SP [Y]. PRE) {SP [FY]. splay (FY ); If (SP [FY]. Pre = 0 ) Printf ( " % D \ n " , Max (SP [Sp [FY]. RS]. Max, SP [Y]. max); SP [Sp [FY]. RS]. Root = True ; SP [FY]. RS = Y, SP [Y]. Root = False ; SP [FY]. Update ();}} Void Solve (){ Int X, Y; Char OP [ 10 ]; For (;) {Scanf ( " % S " , OP ); If (OP [ 0 ] = ' D ' ) Break ; Scanf ( " % D " , & X ,& Y ); If (OP [ 0 ] = ' C ' ) Change (edge [X]. Y, y ); Else If (OP [ 0 ] = ' N ' ) Negate (x, y ); Else Query (x, y );}} Int Main (){ Int T; scanf ( " % D " ,& T ); While (T -- ) {Init (); solve ();} Return 0 ;}