Title Link: BZOJ-3052
Problem analysis
This problem is a very classic tree on the Mo team, and is a modified team mo.
With modified MO team: will be asked according to the left end of the block number is the first keyword, the right end of the block is the second keyword, after the first few changes to the third keyword sorting.
We set the size of the block to n^ (2/3) so that there is a total of n^ (1/3) blocks. The total complexity of the final algorithm would be n^ (5/3).
How do you move from the previous question every time?
Suppose the previous query is (LX, ly, lt), this time the inquiry is (x, y, T). T means after the first T modification operation.
First move T, if T > lt, then the modification operation (lt+1, T) will be done once. If T < LT, start undoing the modification from T, and undo it to Lt+1. In order to be able to undo the modification, we need to preprocess the original color of the location modified by each modification operation.
Then it moves the path on the tree, from (LX, ly) to (x, y). This has a classic approach.
We use S (A, B) to represent all the points on the path from A to B. We do not directly maintain the points on the path of S (x, y), but rather maintain a point on the path of T (x, y), i.e. s (x, y) to remove the LCA (x, y).
This transfer from T (LX, LY) to T (x, Y) needs to be shifted first to T (x, ly), then to T (x, y).
From T (LX, LY) to T (x, LY): We use XOR to denote the symmetry difference of two sets, that is, the occurrence of two times will be offset.
Then T (lx, ly) = S (lx, root) xor S (ly, Root)
T (x, ly) = S (x, Root) xor S (ly, Root)
We xor each of the above two formulas.
T (LX, LY) XOR T (x, ly) = S (lx, root) xor s (x, Root)
T (LX, LY) XOR T (x, ly) = t (lx, X)
T (x, ly) = t (lx, LY) XOR T (LX, X)
We maintain that each point is on the current path, so we only need to change the state of the point on the T (LX, x) to achieve this shift.
From t (x, ly) to T (x, y) the same.
After this transfer, we get T (x, y), and we need to change the state of the LCA (x, y), and then change the state of the LCA back after the answer is recorded. Because we need to maintain the T (x, y).
By the way, the method used to block the tree is the block method of the Royal Commonwealth problem, maintaining a stack.
Currently in the Status of this problem ranked next to WJMZBMR good happy ~
| 46 |
930837 |
Tomriddle |
23684 KB |
80647 MS |
C++ |
4776 B |
2015-04-13 14:38:31 |
| 47 |
348468 |
Wjmzbmr |
12940 KB |
80682 MS |
C++ |
4383 B |
2013-02-12 15:57:06 |
Code
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath > #include <algorithm>using namespace std;inline void Read (int &num) {char c = getchar (); bool Neg = False;while (C < ' 0 ' | | c > ' 9 ') {if (c = = '-') Neg = True;c = GetChar ();} Num = C-' 0 '; c = GetChar (); while (c >= ' 0 ' && C <= ' 9 ') {num = num * + C-' 0 '; c = GetChar ();} if (Neg) Num =-num;} typedef long LONG Ll;const int MAXN = 100000 + 5, MaxQ = 100000 + 5;int N, m, Q, Blksize, Top, Index, Id_index, Chg_index, Qt;int V[MAXN], W[MAXN], COL[MAXN], FATHER[MAXN], ID[MAXN], DEPTH[MAXN], S[MAXN], CNT[MAXN], jump[maxn][20], Ti[MaxN]; LL Ans; LL Ansa[maxq];bool inpath[maxn];struct Edge{int v; Edge *next;} E[MAXN * 2], *p = E, *point[maxn];inline void Addedge (int x, int y) {++p; P-v = y; P-Next = point[x]; POINT[X] = P;} void DFS (int x, int Fa, int Dep) {father[x] = Fa; DEPTH[X] = Dep;int Bottom = top;for (Edge *j = point[x]; j; j = J-Next{if (J-v = = Fa) Continue;dfs (J-V, X, Dep + 1); if (Top-bottom >= blksize) {++id_index;while (Top > Bott OM) id[s[top--]] = Id_index;}} S[++top] = x;} struct Query{int x, y, VX, VY, TL, IDX;} q[maxq];inline bool Cmp (query Q1, query Q2) {if (Q1.VX! = Q2.VX) return Q1.VX < Q2.vx;if (Q1.vy! = Q2.vy) return Q1.vy & Lt Q2.vy;return q1.tl < q2.tl;} struct Chg{int Pos, Num, Prev;} c[maxq];inline void Changecol (int Num, int f) {if (f = =-1) {Ans-= (LL) v[num] * (LL) w[cnt[num]];--cnt[num];} Else{++cnt[num]; Ans + = (LL) v[num] * (LL) w[cnt[num];}} void Changetl (int x, int y) {if (x = = y) return;if (x < y) {for (int i = x + 1; i <= y; ++i) {if (Inpath[c[i]. Pos]) {Changecol (Col[c[i]. Pos],-1); Changecol (C[i]. Num, 1);} Col[c[i]. Pos] = C[i]. Num;}} else{for (int i = x; i > y; i) {if (Inpath[c[i]. Pos]) {Changecol (Col[c[i]. Pos],-1); Changecol (C[i]. Prev, 1);} Col[c[i]. Pos] = C[i]. Prev;}}} inline void Reverse (int x) {if (inpath[x]) {inpath[x] = false; Changecol (Col[x],-1);} else {inpath[x] = tRue Changecol (Col[x], 1);}} void change (int x, int. y) {while (x! = y) {if (Depth[x] < depth[y]) swap (x, y); Reverse (x); x = Father[x];}} int LCA (int x, int y) {if (Depth[x] < depth[y]) swap (x, y); int Dif = depth[x]-depth[y];for (int i = 0; I <=; ++i if (Dif & (1 << i) x = jump[x][i];if (x = = y) return x;for (int i =; I >= 0; i) if (jump[x][i]! = jump[ Y][i]) {x = Jump[x][i];y = Jump[y][i];} return father[x];} void Prepare () {for (int i = 1; I <= n; ++i) jump[i][0] = father[i];for (int j = 1; J <=), ++j) for (int i = 1; I &l t;= N; ++i) Jump[i][j] = jump[jump[i][j-1]][j-1];} int main () {Read (n); Read (m); Read (q); for (int i = 1; I <= m; ++i) read (V[i]); for (int i = 1; I <= n; ++i) read (w[i]); int A, b;for (int i = 1; I & Lt;= n-1; ++i) {Read (a); Read (b); Addedge (A, b); Addedge (b, a);} for (int i = 1; I <= n; ++i) Read (Col[i]); blksize = (int) POW (n, 0.667);D FS (1, 0, 0), while (Top > 0) id[s[top--]] = Id_index; Prepare (); for (int i = 1; I <= n; ++i) ti[I] = col[i];int f;for (int i = 1; I <= Q; ++i) {Read (f); Read (a); Read (b); if (f = = 0) {++chg_index; C[chg_index]. Prev = Ti[a]; Ti[a] = b; C[chg_index]. Pos = A; C[chg_index]. Num = b;} ELSE{++QT; q[qt].x = A; Q[qt].y = b; Q[QT].VX = Id[a]; Q[qt].vy = Id[b]; q[qt].tl = Chg_index; Q[QT]. IDX = Qt;}} Sort (q + 1, q + Qt + 1, CMP); Ans = 0LL; Changetl (0, q[1].tl); Change (q[1].x, q[1].y); int t = LCA (q[1].x, Q[1].Y); Reverse (t); ANSA[Q[1]. IDX] = Ans; Reverse (t); for (int i = 2; I <= Qt; ++i) {Changetl (q[i-1].tl, q[i].tl); Change (q[i-1].x, q[i].x); Change (q[i-1].y, q[i].y); t = LCA (q[i].x, Q[I].Y); Reverse (t); Ansa[q[i]. IDX] = Ans; Reverse (t);} for (int i = 1; I <= Qt; ++i) printf ("%lld\n", Ansa[i]); return 0;}
[Bzoj 3052] [wc2013] Candy Park "tree on the MO team"