Hdu2763 housewife wind

Source: Internet
Author: User

Given a tree with edge weights at n (n <100001) nodes, perform the following Q (q <100001) operations:

1. Change the right of an edge of the tree;

2. Calculate the distance between the given vertex and a certain vertex. The latter is the node numbered 1. If operation 2 is executed for the first time, otherwise it is the given point for the last operation 2.

Analysis: If operation 1 is not performed, that is, the edge weight is not changed, it is a common problem to convert the value from LCA to rmq. If the edge weight is changed, does it mean that all the pre-processed data is useless? Otherwise, changing the weight of an edge will have a fixed impact on those edges. That is to say, if the Euler sequence is fixed, the weight of an edge will be changed, the DIS [] value of the entire subtree (distance from the root node) is changed, while in the Euler's sequence, the entire subtree is continuous ,, you only need to record the start and end positions of each node in the Euler's sequence by the way, which is a range of the Euler's sequence...

You can use a tree array to maintain a dis1 [I], that is, the difference between it and the original dis [I] after the change ..

View code

# Include <iostream> # Include <Algorithm> # Include < String . H> # Include <Math. h># Include <Stdio. h> Using   Namespace  STD;  Const   Int N = 100000 + 10  ;  Struct  Edge {  Int  V, NEX, W;} e [n * 2  ];  Struct Edge {  Int  U, V;  Int  W;} e [N];  Int  Head [N], size, N;  Int F [ 2 * N], B [ 2 * N], pos_s [N], pos_e [N], DIS [N], Bn;  Int Tree [ 2 * N], DP [N * 2 ] [ 20 ];  Bool  Vis [N];  Void  Init () {memset (Head, - 1 , Sizeof  (Head); memset (VIS,  False , Sizeof  (VIS); Size = 0  ;}  Void Insert ( Int U,Int V, Int  W) {e [size]. v = V; E [size]. W = W; E [size]. NEX = Head [u]; head [u] = Size ++ ;}  //  Dis [] records the distance from each node to the root node  //  F [] corresponds to the Euler's sequence, and B [] is the depth of each vertex corresponding to the Euler's sequence (this is obtained through the estimation of LCA)  //  Pos_s [] and pos_e [] respectively record the start and end positions of nodes in the Euler's sequence.  Void DFS ( Int Cur, Int Deep, Int  Len) {vis [cur] = True  ; DIS [cur] = Len; F [bn] = Cur; B [bn] = Deep; pos_s [cur] = Bn ++ ;  For ( Int I = head [cur]; I! =- 1 ; I =E [I]. NEX ){  Int V = E [I]. V;  If (! Vis [v]) {DFS (v, deep + 1 , Len + E [I]. W); F [bn] = Cur; B [bn] = Deep; bn ++ ;}} Pos_e [cur] = BN- 1  ;}  Void Init_rmq () {memset (DP,  0 , Sizeof  (DP ));  For ( Int I = 1 ; I <= Bn; ++ I) DP [I] [  0 ] = I;  For ( Int J = 1 ; J <= Log (( Double ) (BN +1 )/Log ( 2.0 ); ++ J ){  Int Limit = Bn + 1 -( 1 < J );  For ( Int I = 1 ; I <= limit; ++ I ){  Int X = DP [I] [J- 1  ]; Int Y = DP [I + ( 1 <(J- 1 )] [J- 1  ]; DP [I] [J] = B [x] <B [y]? X: Y ;}}}  Int Rmq ( Int A, Int  B ){  If (A> B) Swap (A, B );  Int K = ( Int ) (Log (( Double ) (B-A + 1 )/Log ( 2.0  ));  Int X = DP [a] [k];  Int Y = DP [B + 1 -( 1 < K)] [k];  Return B [x] <B [y]? X: Y ;}  Int Lowbit ( Int X ){  Return X &(- X );}  Void Modify ( Int X, Int  Add ){  While (X < 2 * N) {tree [x] + = Add; x + = Lowbit (x );}}  Int Get_val ( Int X)//  Single Point  {  Int Ret = 0  ;  While (X> 0  ) {RET + = Tree [X]; x -= Lowbit (x );}  Return  RET ;}  Int  Main (){  Int Q, S;  Int  A, C;  Int  OP;  While (Scanf ( "  % D  " , & N, & Q, & S) = 3  ) {Init ();  For ( Int I = 1 ; I <n; ++ I) {scanf ( "  % D  " , & E [I]. U, & E [I]. V ,& E [I]. w); insert (E [I]. u, E [I]. v, E [I]. w); insert (E [I]. v, E [I]. u, E [I]. w);} bn = 1  ; DFS (  1 , 0 , 0  ); -- Bn; init_rmq (); memset (tree,  0 , Sizeof (Tree ));  While (Q -- ) {Scanf (  "  % D  " ,& OP );  If (OP = 0  ) {Scanf (  "  % D  " ,& A );  Int T = rmq (pos_s [s], pos_s [a]); //  Returns the subscript of the closest common ancestor in the Euler's sequence.                  Int Ans = get_val (t) + dis [f [T]; //  Get_val (t) only obtains the change value of the distance between the point marked as T in the Euler's sequence and the original distance. Ans = get_val (pos_s [s]) + dis [s]- 2 * Ans; ans + = Get_val (pos_s [a]) + Dis [a]; printf (  "  % D \ n  "  , ANS); s =A ;}  Else  {Scanf (  "  % D  " , & ,& C );  Int W = c-e [A]. W, U; //  Changed weight E [A]. W = C;  If (DIS [E [A]. u] <dis [E [A]. V]) //  Determine the node subtree that should be changed U = E [A]. V;  Else U = E [A]. U;  Int L = pos_s [u], r = Pos_e [u];  //  Cout <L <''<r <Endl; Modify (R + 1 ,- W); Modify (L, W );  //  The two operations change the range [L, R], which corresponds to the range of the Euler's sequence.  }}} Return   0  ;} 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.