树形转线性,然后用树状数组维护就行,单点更新,区间查询,但是辣鸡POJ卡vector窝日,所以用链式前向星存就行
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define maxn 100005
#define maxm 200010
struct Edge
{
int next, to;
Edge() :next(0), to(0){ }
}edge[maxm];
int head[maxn], cnt = 0;
int idx[maxn];
int low[maxn];
bool vis[maxn];
bool apple[maxn];
int bit[maxn];
int N, M;
int pos = 0;
void add(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void DFSidx(int u)
{
idx[u] = ++pos;
vis[u] = true;
for (int i = head[u]; i != -1; i=edge[i].next)
{
if (vis[edge[i].to])
continue;
DFSidx(edge[i].to);
}
low[u] = pos;
}
//更新点查询区间
int query(int i)
{
int sum = 0;
while (i)
{
sum += bit[i];
i -= i&(-i);
}
return sum;
}
void update(int i, int val)
{
while (i <= N)
{
bit[i] += val;
i += i&(-i);
}
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
memset(head, -1, sizeof(int)*maxn);
scanf("%d", &N);
int u, v;
for (int i = 0; i < N - 1; ++i)
{
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
DFSidx(1);
scanf("%d", &M);
int sum;
char cmd[4];
for (int i = 0; i < M; ++i)
{
scanf("%s%d", cmd, &u);
if (cmd[0] == 'C')
{
if (apple[idx[u]])
{
update(idx[u], -1);
apple[idx[u]] = false;
}
else
{
update(idx[u], 1);
apple[idx[u]] = true;
}
}
else
{
sum = query(low[u]) - query(idx[u] - 1);
printf("%d\n", low[u] - idx[u] + 1 - sum);
}
}
//system("pause");
//while (1);
return 0;
}