先做一次dfs求得每个节点为根的子树在树状数组中编号的起始值和结束值,再树状数组做区间查询 与单点更新。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 100008, INF = 0x3F3F3F3F;
#define MS(a, num) memset(a, num, sizeof(a))
int leftid[N], rightid[N];
struct Node{
int to,next;
}edge[2 * N];
int head[N],tot;
void init(){
memset(head, -1, sizeof(head));
tot = 0;
}
inline void addedge(int u, int to){
edge[tot].to=to;
edge[tot].next=head[u];
head[u]=tot++;
}
int n, m;
bool sta[N];
int C[N];
inline int lowbit(int x){
return x&-x;
}
inline void add(int x, int val){
for(int i=x;i<=n;i+=lowbit(i)){
C[i] += val;
}
}
inline int sum(int x){
int ret = 0;
for(int i=x;i>0;i-=lowbit(i)){
ret+=C[i];
}
return ret;
}
int cnt = 0;
void dfs(int u, int fa){
leftid[u] = cnt + 1;
for(int i = head[u]; ~i ; i = edge[i].next){
int v = edge[i].to;
if(v != fa){
dfs(v, u);
}
}
rightid[u] = ++cnt;
}
int main(){
while(~scanf("%d", &n) && n){
MS(C, 0);
init();
for(int i = 1; i <= n; i++){
add(i, 1);
sta[i] =1;
}
int u, v;
for(int i = 0; i < n -1; i++){
scanf("%d %d", &u, &v);
addedge(u, v);
addedge(v, u);
}
cnt = 0;
dfs(1, -1);
cin>>m;
char ope;
while(m--){
scanf(" %c %d", &ope, &u);
int l = leftid[u], r = rightid[u];
if(ope == ‘C‘){
if(sta[r]){
sta[r] = 0;
add(r, -1);
}else{
sta[r] = 1;
add(r, 1);
}
}else{
int tp = sum(r) - sum(l - 1);
printf("%d\n", tp);
}
}
}
return 0;
}