Spoj_2798
If you use link-cut-tree to write data, you only need to maintain the col (node color) and sum (number of black nodes in the subtree) labels. During the dyeing process, the corresponding node splay is added to the root node and then modified. The access (v) operation is performed first during the query, and then the root of the splay is searched recursively, if the sum value of the root node is 0,-1 is output.
# Include <stdio. h> # Include < String . H> # Define Maxd 100010 # Define Maxm 200010 Int N, Q, Q [maxd], first [maxd], E, next [maxm], V [maxm]; Struct Splay { Int PRE, ls, RS, Col, sum; Bool Root; Void Update (); Void Zig ( Int ); Void Zag ( Int ); Void Splay ( Int ); Void RENEW () {Root =True ; Pre = Ls = rs = 0 ; Col = 0 , Sum = 0 ;}} SP [maxd]; Void Splay: Update () {sum = Sp [ls]. Sum + SP [RS]. Sum + Col ;} Void Splay: Zig ( Int X ){ Int Y = RS, fa =Pre; 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; 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 (;! 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) {v [E] = Y; next [E] = First [X], first [x] = e ++ ;} Void Prepare (){ Int I, j, X, rear =0 ; SP [ 0 ]. Sum = 0 ; Q [rear ++] = 1 ; SP [ 1 ]. RENEW (); 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; Q [rear ++] = V [J] ;}} Void Init (){ Int I, X, Y; memset (first, - 1 , Sizeof (First); e =0 ; For (I = 1 ; I <n; I ++ ) {Scanf ( " % D " , & X ,& Y); add (x, y), add (Y, x);} prepare ();} Void Change ( Int X) {SP [X]. splay (x); SP [X]. Col ^ = 1 ; SP [X]. Update ();} 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 ();}} Int Search ( Int Cur ){ If (SP [Sp [cur]. ls]. Sum! = 0 ) Return Search (SP [cur]. ls ); Else If (SP [cur]. col) Return Cur; Else Return Search (SP [cur]. RS );} Void Ask ( Int X ){ Int Y; Access (X ); For (Y = x ;! SP [Y]. root; y = SP [Y]. PRE ); If (SP [Y]. Sum = 0 ) Printf ( " -1 \ n " ); Else Printf ( " % D \ n " , Search (y ));} Void Solve (){ Int I, op, X; For (I = 0 ; I <q; I ++ ) {Scanf ( " % D " , & OP ,& X ); If (OP = 0 ) Change (X ); Else Ask (x );}} Int Main (){ While (Scanf ( " % D " , & N, & Q) = 2 ) {Init (); solve ();} Return 0 ;}