Various LCT operations ....
Cut link add Mul size rev Query
Write efficiency is not high enough... On bzoj, it seems that TLE ....
A1303. tree (Wu yiming) Time Limit: 2.5 s memory limit: 64.0 MB total submissions: 727 AC times: 238 average score: 45.59 share this question: view unformatted questions submit questions discuss question source 2012 China National Training Team question description a tree of N points, the initial weight of each point is 1. There are Q operations for this tree. Each operation is one of the following four operations:
+ U v c: add the natural number C to the weights of vertices in the U-V path;
-U1 V1 U2 V2: deletes the original edge (U1, V1) of the tree and adds a new edge (U2, V2) to ensure that it is still a tree after the operation;
* U v c: multiply the weights of vertices from u to V by natural numbers C;
/U v: Ask the sum of the vertex weights in the path from u to V, and find the remainder of the answer for 51061. The first line of the input format is two integers n, Q
The next n-1 line contains two positive integers U and V, which describe the tree.
Next, in the Q row, each row describes an operation output format. For each/corresponding answer, output a line. Example input is 3 2.
1 2
2 3
* 1 3 4
/1 Example 1 output 4 data scale and agreed 10% data guarantee, 1 <= N, q <= 2000
In addition, 15% of Data guarantee, 1 <= N, q <= 5*10 ^ 4, no-operation, and the initial tree is a chain
In addition, 35% of Data guarantee, 1 <= N, q <= 5*10 ^ 4, no-operation
100% data guarantee, 1 <= N, q <= 10 ^ 5, 0 <= C <= 10 ^ 4
Submit questions for discussion
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> using namespace STD; typedef long int ll; const int maxn = 100100; const ll mod = 51061; int ch [maxn] [2], pre [maxn]; bool rev [maxn], RT [maxn]; ll size [maxn], key [maxn], add [maxn], mul [maxn], sum [maxn]; void update_add (int r, ll d) {If (! R) return; If (D = 0) return; key [R] = (Key [R] + d) % MOD; add [R] = (add [R] + d) % MOD; sum [R] = (size [R] * D + sum [R]) % MOD ;} void update_mul (int r, ll d) {If (! R) return; If (D = 1) return; sum [R] = (sum [R] * D) % MOD; key [R] = (Key [R] * D) % MOD; Mul [R] = (Mul [R] * D) % MOD; add [R] = (add [R] * D) % MOD;} void update_rev (int r) {If (! R) return; swap (CH [r] [0], CH [r] [1]); rev [R] = rev [R] ^ 1 ;} void push_down (int r) {If (! R) return; If (Rev [R]) {If (CH [r] [0]) update_rev (CH [r] [0]); if (CH [r] [1]) update_rev (CH [r] [1]); rev [R] = 0;} If (Mul [R]! = 1) {If (CH [r] [0]) update_mul (CH [r] [0], mul [R]); If (CH [r] [1]) update_mul (CH [r] [1], mul [R]); Mul [R] = 1;} If (add [R]) {If (CH [r] [0]) update_add (CH [r] [0], add [R]); If (CH [r] [1]) update_add (CH [r] [1], add [R]); add [R] = 0 ;}} void push_up (int r) {sum [R] = Key [R] % MOD; Size [R] = 1; if (CH [r] [0]) {sum [R] = (sum [R] + sum [CH [r] [0]) % MOD; size [R] + = size [CH [r] [0];} If (CH [r] [1]) {sum [R] = (sum [R] + sum [CH [r] [1]) % MOD; Size [R] + = Si Ze [CH [r] [1] ;}} void rotate (int x) {int y = pre [X], kind = CH [y] [1] = x; ch [y] [kind] = CH [x] [! Kind]; Pre [CH [y] [kind] = y; Pre [x] = pre [y]; Pre [y] = x; ch [x] [! Kind] = y; If (RT [y]) rt [y] = false, RT [x] = true; else ch [pre [x] [CH [pre [x] [1] = y] = x; push_up (y);} void P (int r) {If (! RT [R]) P (pre [R]); push_down (r);} void splay (int r) {P (r); While (! RT [R]) {int F = pre [R], FF = pre [f]; If (RT [f]) rotate (R ); else if (CH [ff] [1] = f) = (CH [f] [1] = r) rotate (F), rotate (R ); else rotate (R), rotate (r);} push_up (r);} int access (int x) {int y = 0; For (; X; X = pre [Y = x]) {splay (x); RT [CH [x] [1] = true; RT [CH [x] [1] = y] = false; push_up (x);} return y;} void mroot (int r) {access (R ); splay (r); update_rev (r);} void Link (int u, int v) {mroot (U); Pre [u] = V;} void cut (int u, int v) {m Root (U); splay (V); Pre [CH [v] [0] = pre [v]; Pre [v] = 0; RT [CH [v] [0] = true; ch [v] [0] = 0; push_up (V);} void add (int u, int V, ll d) {mroot (U); Access (V); splay (V); update_add (v, d);} void MUL (int u, int V, ll D) {mroot (U); Access (V); splay (V); update_mul (v, d);} void debug (); void query (int u, int V) {mroot (U); Access (V); splay (V); // cout <"Size:" <size [v] <"sum: "<sum [v] <Endl; printf (" % LLD \ n ", sum [v]);} struct ed GE {int to, next;} edge [maxn * 2]; int adj [maxn], size; void add_edge (int u, int v) {edge [size]. to = V; edge [size]. next = adj [u]; adj [u] = size ++;} int N, Q; void Init () {size = 0; For (INT I = 0; I <= N + 10; I ++) {adj [I] =-1; ch [I] [0] = CH [I] [1] = 0; pre [I] = 0; RT [I] = true; rev [I] = false; key [I] = 1; Size [I] = 1; add [I] = 0; Mul [I] = 1; sum [I] = 1 ;}} void DFS (int u) {for (INT I = adj [u]; ~ I; I = edge [I]. Next) {int v = edge [I]. To; If (pre [v]! = 0) continue; Pre [v] = u; DFS (v) ;}} void showit (int x) {If (x) {push_down (X ); showit (CH [x] [0]); printf ("node: % 2D left son: % 2D right son: % 2D parent node: % 2D size: % 2lld sum: % 2lld key: % 2lld \ n ", X, CH [x] [0], CH [x] [1], pre [X], size [X], sum [X], key [x]); showit (CH [x] [1]) ;}} void debug () {for (INT I = 0; I <= N; I ++) {If (RT [I]) {cout <"root:" <I <Endl; showit (I ); cout <".......... \ n ";}} int main () {While (scanf (" % d ", & N, & Q )! = EOF) {Init (); For (INT I = 0; I <n-1; I ++) {int U, V; scanf ("% d ", & U, & V); add_edge (u, v); add_edge (v, U);} Pre [1] =-1; DFS (1 ); pre [1] = 0; // debug (); char op [10]; while (Q --) {scanf ("% s", OP ); if (OP [0] = '+') {int U, V, C; scanf ("% d", & U, & V, & C); add (u, v, c);} else if (OP [0] = '-') {int u1, V1, U2, V2; scanf ("% d", & u1, & V1, & U2, & V2); cut (U1, V1); Link (U2, v2);} else if (OP [0] = '*') {int U, V, C; scanf ("% d", & U, & V, & C); MUL (u, v, c);} else if (OP [0] = '/') {int U, V; scanf ("% d", & U, & V); query (u, v) ;}// debug () ;}} return 0 ;}
Tsinsen a1303. tree (Wu yiming) LCT