Apple Tree Time limit:2000ms Memory limit:65536k Total submissions:16705 accepted:5051
Description
There is a apple tree outside the Kaka ' s house. Every Autumn, a lot of apples would grow in the tree. Kaka likes Apple very much more, so his has been carefully nurturing the Big Apple tree.
The tree has N forks which are connected by branches. Kaka numbers the forks by 1 to N and the root is always numbered by 1. Apples'll grow on the forks and two Apple won ' t grow on the same fork. Kaka wants to know I many apples are there in a sub-tree, for his study of the produce of the apple tree.
The trouble is this a new Apple may grow on a empty fork some time and Kaka could pick an apple from the "tree" to his Desse Rt. Can you help Kaka?
Input
The contains an integer N (n≤100,000) and which is the number of the forks in.
The following N-1 lines each contain two integers u and V, which means-u and Fork v fork are by a connected.
The next line contains an integer M (m≤100,000).
The following M lines each contain a message which is either
"C X" which means the existence of the Apple on Fork X has been. i.e. if there is a apple on the fork, then Kaka pick it; Otherwise a new Apple has grown on the empty fork.
Or
"Q X" which means an inquiry for the number of apples in the sub-tree above the fork X, including the Apple (if exists) on The fork X
The ' is ' full ' apples at the beginning
Output for every inquiry, output the correspond answer/line.
Sample Input
3
1 2
1 3
3
q 1
C 2
q 1
Sample Output
3
2
Source POJ monthly--2007.08.05, Huang, Jinsong
It is obvious that a maintenance of a single point query interval of the topic but in the beginning did not see the meaning of any interval is clearly a tree ah ...
There's actually something called a timestamp. The time stamp is a DFS-ordered point to mark a start time an end time so from the start time to the end time is the interval between it and its child nodes
#include <iostream> #include <cstdio> #include <cstring> using namespace std;
const int lim=200011;
int sumv[lim<<2],bt[lim],et[lim]; struct Self{int x,y;}
s[lim<<1];
int first[lim<<1],nxt[lim<<1];
int m,n,a,b,c;
Char Chin;
void pushup (int o) {sumv[o]=sumv[o<<1]+sumv[o<<1|1];}
int x,y;
int query (int o,int l,int R) {if (l>=x&&r<=y) return sumv[o];
int m= (L+R) >>1,ret=0;
if (x<=m) ret+=query (o<<1,l,m);
if (y>m) ret+=query (o<<1|1,m+1,r);
return ret;
} void Update (int o,int l,int R) {if (l==r) {sumv[o]^=1;
Return
int m= (L+R) >>1;
if (x<=m) update (O<<1,L,M);
else update (O<<1|1,M+1,R);
Pushup (o);
} void makeside (int i,int x,int y) {s[i].x=x;s[i].y=y;
NXT[I]=FIRST[X];
First[x]=i;
} void Build (int o,int l,int R) {if (l==r) {sumv[o]=1;
Return
int m= (L+R) >>1; Build (O<<1,L,M);
Build (O<<1|1,m+1,r);
Pushup (o);
} bool Flag[lim];
int t;
void Maketree (int i) {flag[i]=1;
t++;
bt[i]=t;
for (int e=first[i];e!=-1;e=nxt[e]) if (!FLAG[S[E].Y)) Maketree (S[E].Y);
et[i]=t;
int main () {scanf ("%d\n", &m);
memset (First,-1,sizeof (a));
memset (nxt,-1,sizeof (NXT));
for (a=1;a<m;a++) {scanf ("%d%d\n", &x,&y);
Makeside (A,x,y);
Makeside (A+M,Y,X);
} maketree (1);
Build (1,1,M);
scanf ("%d\n", &n);
for (a=1;a<=n;a++) {scanf ("%c%d\n", &chin,&b);
X=BT[B],Y=ET[B];
if (chin== ' Q ') printf ("%d\n", Query (1,1,m));
else update (1,1,M);
return 0;
}