Title Description Description
Outside the Kaka's house, there is an apple tree. Every spring, there is always a lot of apples on the tree. Kaka was very fond of apples, so he always cared for the apple tree. We know that there are a lot of fork points in the tree, Apple will be on the fork point of the branches, and no more than two apples knot together. Kaka would like to know the number of apples on the subtree represented by a fork point, so as to study which branches of the apple tree have a stronger result.
What Kaka knows is that some of the apples will be on some forks at some point, but what Kaka doesn't know is that there are always some naughty kids to pick some apples off the tree.
So we define two operations:
C x
Indicates that the state of the fork point with the number x is changed (the original is an apple, it is removed, the original is not, the knot an apple)
Qx
How many apples are there in the subtree represented by a fork point that has a number x?
We assume that at the outset, all the trees were apples, and also included the fork 1 as the root node.
Enter a description input Description
First row one number n (n<=100000)
Next n-1 line, 2 number u,v per line, indicates that the fork point U and Fork Point v are directly connected.
Next line a number M, (m<=100000) indicates the number of queries
The next M-line, which represents the query, asks the format as described in the question Q X or C x
outputs description output Description
For each q x query, output the corresponding result, each line output a
sample input to sample
3
1 2
1 3
3
Q 1
C 2
Q 1
sample output Sample outputs
3
2
- Exercises
- A look at this data size and input method can basically be identified as a high-level data structure problem. Do a lot of questions about the tree, I feel that the tree actually corresponds to a period of time, that is, its traversal order, a lot of maintenance methods can be based on this traversal sequence .
- The middle sequence traversal of binary tree is special, and it is fully embodied in this Noip2003 two-fork tree. That topic uses the middle sequence traversal to carry on the interval DP, and has obtained the good effect.
- But the normal tree does not have the middle sequence traversal, but its own first root traverse and the post root traversal also have many particularity.
- First, a depth-first traversal of the tree, with a DFN array (timestamp) to mark the entire tree to access the node order, because the order of the subtrees tree access is continuous!
- Such a subtrees tree can be extracted as an interval . The subject only involves the modification and query of individual nodes in the tree, so we can think of the tree array and the line segment tree immediately.
- If you use the first root traversal, then you need to record the timestamp of the node that is most visited at the bottom of each subtrees tree , so that the subtrees tree can use the timestamp of the root of the subtree and the time stamp of the node that is most visited at the sub-tree . extracted from the sequence of the preceding root traversal. Similarly, using the post-root traversal requires logging The timestamp of the node to which each subtrees tree was first accessed .
The following is a good solution:
C operation, directly to the time stamp modification in the traversal sequence of the corresponding node can be;
Q operation, the time stamp in the traversal sequence corresponding to the interval and can be;
Code—————— Maintaining the post-root traversal sequence with the ZKW segment tree
#include <cstdio>#include <cstring>#include <vector>#include <iostream>#include <algorithm>using namespace STD;Const intMAXN =100010, nil =0, root =1;intN, M, LC[MAXN], DFN[MAXN];intT[MAXN <<2], delta, tot;//zkw segment tree, tot is the access order vector <int>TREE[MAXN];BOOL*vis;//Because the parent-child relationship of the side is not explicitly given, so the two-way Tim Edge, when traversing this vis record node has been visitedintDfsintRot//Return the leftmost son of a subtree rooted in Rot{intRT =0;BOOLb =false; Vis[rot] =true; for(inti =0; I < tree[rot].size (); ++i)if(!vis[tree[rot][i]]) {b =true; RT = DFS (Tree[rot][i]);if(Lc[rot] = nil) lc[rot] = RT; } Dfn[rot] = ++tot;if(b)returnLc[rot];Else returnLc[rot] = Dfn[rot];}voidInit () {intU, v;Cin>> N;//Segment Tree initialization for(Delta =2; Delta <= (n <<1) +1; Delta <<=1); for(inti = Delta +1; I <= Delta + N; ++i) T[i] =1; for(inti = delta-1; I >=1; I.) T[i] = T[i <<1] + t[i <<1|1];//Initialization End for(inti =1; I < n; ++i) {Cin>> u >> v; Tree[u].push_back (v); Tree[v].push_back (U); } Vis =New BOOL[MAXN];memset(Vis,false,sizeof(VIS)); DFS (root);Delete[] vis; Vis = NULL; for(inti =1; I <= N; ++i) tree[i].clear ();//Less use of memory, the evaluation machine Gentle point Cin>> m;}voidChangeintX//single-point modification{ for(t[x + = Delta] ^=1, x >>=1; X X >>=1) T[x] = t[x <<1] + t[x <<1|1];}intQueryintLintR//Interval query{if(L = = r)returnT[l + Delta];intAns =0; for(L + = delta-1, r + = Delta +1; L ^ R ^1; L >>=1, R >>=1) {if(~l &1) ans + = t[l ^1];if(R &1) ans + = t[r ^1]; }returnAns;}voidWork () {CharOptintX while(m--) {Cin>> opt >> x;if(opt = =' Q ')cout<< query (Lc[x], dfn[x]) << Endl;ElseChange (dfn[x]); }}intMain () {init (); Work ();return 0;}
Codevs1128 Apple Tree