Given a tree, each node is black at the beginning. Now there is a Q group operation, or ask how far the two black trees are from, or change the color of a point.
Solution: after reading the thesis and reference code for a day, I feel that the process of model conversion has been very clever.
1. Select a root node from the tree with a tree structure, convert the linear structure through DFS search, and then describe the distance problem using brackets.
2. after being described using parentheses, we find that the distance between any two points is to reach a stable State through some elimination of the parentheses sequence, and then obtain the distance information in the stable state.
3. We found that the sequence of parentheses can be merged, so the line segment tree is useful. This is obviously a merge process of dynamic planning. The line segment tree question about the range is nothing more than maintaining such a few quantities, separate intervals, left continuous intervals, and right continuous intervals. Because each stable state requires two records, the number of left and right brackets, it is not easy to maintain. A good change can make the length be deduced from each other, therefore, you only need to maintain the length of the three quantities mentioned above and keep the stable state of the current interval for calculating the length of the entire interval.
In short, various gods ......
Island maiden question: http://www.shuizilong.com/house/archives/bzoj-1095-zjoi2007hide-%E6%8D%89%E8%BF%B7%E8%97%8F/
The Code is as follows:
# Include <cstdlib> # include <cstring> # include <cstdio> # include <iostream> # include <algorithm> using namespace STD; int N, Q, CNT; const int maxn = 100005; const int MaxE = 500005; const int INF = 0x3fffffff; int V [maxn * 3], POS [maxn]; char sta [maxn]; struct edge {int V, next;} eg [MaxE <1]; int idx, head [maxn]; /* What is a processing like "[[] [[] [] [" to eliminate a matching condition for the left-side brackets is the meaning of processing brackets: '[' indicates the number of layers plus 1'] 'indicates the number of layers minus 1. If the number of layers first drops and then increases during a DFS Process Then, returning from a point X (in the I layer) to the I layer again means that the path length of the node from X to the later will be unrelated to the previous descent-up process. The elimination of the brackets mentioned above is to delete these useless processes, and the remaining "] [[[[" string length is the desired distance. If we use number 2 to Represent '[', number 5 To Represent ']', then the upper string is changed to 225555, and the length of 2 and 5 in the line segment tree is counted, and the variables required for the functions of range 2 and 5. A 25 string must appear between two black spots. [L, R] can be expressed using a number pair: (A, B) this indicates that after processing, there will be a 2 in the range, and B 5 will actually be directed to layer a from node l to node R, and then to layer B. We can see from its conclusion that this is a tough journey, and is the shortest path. Now consider the merging of two intervals: the known intervals [a, B] are (A1, B1), and [B, c] are (A2, B2) in fact, it is necessary to calculate the distance from A to C. Obviously, it is not required that B must be a black spot, but A and D must be a black spot. Considering the situation where B is located, from A to C is a descending posture, and from B to C is a rising posture. According to the principle of eliminating parentheses, there are also some parentheses that can be eliminated. In this case, we need to see whether there are more drops on the left or more increases on the right. The values are determined based on different situations and the expressions are as follows: if (b1 <A2) after merging is (A1 + a2-b1, B2), the length after merging is (a1-b1) + (A2 + b2) if (b1> = a2) after merging (A1, b1-a2 + b2), the merged length is (A1 + B1) + (b2-a2) actually the last length can be written as: max (a1-b1) + (A2 + b2), (A1 + B1) + (b2-a2), so that they do not have to consider their location relationship, we only need to care about their respective lengths. Therefore, we need to keep an optimal (a-B) AND (B-A) in the merge interval) of course, not all merged solutions must be the optimal solution. Therefore, you need to record the optimal solution of a single interval, and the merged results must be sent to the father.. Second, we need to retain a description of the entire range to cope with the merger plan covering the entire child range. To sum up the distance between any two black points in the previous interval, the following situations may occur: 1. 2. contains the portion from the left and right sides and the portion from the right */struct node {// The following intervals refer to the processed intervals, that is, 25 strings in the form of] [[in the form of int C2; // record the length of [L, R] remainder, that is, the length of 2 on the left of the 25 string, int C5; // record the length of the remaining '[' in [L, R], that is, the length of 5 on the right of the 25 string, int M25; // record the farthest distance between two black spots in the [L, R] interval, that is, the longest 25 int L25 that meets the requirements; // record the longest 25 string intervals of L, it is not required that the left side of l be a black spot, and the right endpoint must be a black spot int r25; // The record contains the longest 25 string intervals of R, and the right side of R is not required to be a black spot, the left endpoint must be the black spot int L5; // The maximum length difference between 5 and 2 of the records containing L, and the right endpoint must be the black spot int R2; // The records contain the r most The difference between the length of 2 and 5. The left endpoint must be the black dot void Init (int x);} e [maxn * 12]; void node: Init (int x) {C2 = V [x] =-2; C5 = V [x] =-5; M25 =-INF; If (V [x]> 0 &&! Sta [V [x]) {L25 = r25 = L5 = R2 = 0;} else {L25 = r25 = L5 = R2 =-INF ;}} void insert (int A, int B) {eg [idx]. V = B; eg [idx]. next = head [a]; head [a] = idx ++;} void DFS (int u) {v [CNT ++] =-5; // rear drive brackets "[" POS [u] = CNT; V [CNT ++] = u; For (INT I = head [u]; ~ I; I = eg [I]. Next) {If (! (~ Pos [eg [I]. v]) {DFS (eg [I]. v) ;}} V [CNT ++] =-2; // brackets "]"} void push_up (int p, int LL, int RR) {int L = P <1, R = P <1 | 1; // for an update of the entire interval, the coordinates must be determined by E [p]. c2 = E [l]. c5> E [R]. c2? E [l]. c2: E [l]. c2 + E [R]. c2-e [l]. c5; E [p]. c5 = E [l]. c5> E [R]. c2? E [R]. c5 + E [l]. c5-e [R]. c2: E [R]. c5; // E [p]. c2 = E [l]. c2 + max (0, E [R]. c2-e [l]. c5); // E [p]. c5 = E [R]. c5 + max (0, E [l]. c5-e [R]. c2); // you can obtain a part directly from the left and right children, or use a max value to avoid the coordinate E [p] After the range is merged. m25 = max (E [l]. m25, E [R]. m25), max (E [l]. r25 + E [R]. l5, E [R]. l25 + E [l]. r2); // If the left side is consecutive, the length is obtained from the left side or the max function is used to calculate the length. The principle is the same as that of M25. // E [l]. c2 + E [l]. c5 + E [R]. l5 is equivalent to the left interval (A + B), and the right interval (B-a). // E [l]. c2-e [l]. c5 + E [R]. r25 is equivalent to the left range (a-B), and the right range (A + B) E [p]. l25 = max (E [l]. l25, max (E [l]. c2 + E [l]. c5 + E [R]. l5, E [l]. c2-e [l]. c5 + E [R]. l25); e [p]. r25 = max (E [R]. r25, max (E [R]. c2 + E [R]. c5 + E [l]. r2, E [R]. c5-e [R]. c2 + E [l]. r25); // here is the sum of the Difference values between the two intervals, which can be directly added. You do not need to consider removing the impact E [p]. l5 = max (E [l]. l5, E [l]. c5-e [l]. c2 + E [R]. l5); e [p]. r2 = max (E [R]. r2, E [R]. c2-e [R]. c5 + E [l]. r2);} void build (int p, int L, int R) {If (L! = R) {int mid = (L + r)> 1; build (P <1, L, mid); Build (P <1 | 1, mid + 1, R); push_up (P, L, R);} else {e [p]. init (l); // initialize the leaf node} void modify (int p, int L, int R, int X) {If (L = r) {e [p]. init (l) ;}else {int mid = (L + r) >>1; If (x <= mid) Modify (P <1, L, mid, x); else modify (P <1 | 1, Mid + 1, R, x); push_up (P, L, R) ;}} int main () {int A, B, black; char op [5]; while (scanf ("% d", & N )! = EOF) {CNT = idx = 0; black = N; memset (Head, 0xff, sizeof (head); memset (Pos, 0xff, sizeof (POS )); memset (STA, 0, sizeof (STA); For (INT I = 1; I <n; ++ I) {scanf ("% d", &, & B); insert (a, B), insert (B, A);} DFS (1); Build (1, 0, cnt-1); scanf ("% d ", & Q); While (Q --) {scanf ("% s", OP); If (OP [0] = 'G') {If (Black = 0) puts ("-1"); else if (Black = 1) puts ("0"); else printf ("% d \ n", E [1]. m25 );} Else {scanf ("% d", & A); black + = sta [a]? 1:-1; STA [a] =! Sta [a]; Modify (1, 0, cnt-1, POS [a]) ;}} return 0 ;}