#include #include #include #include #include #include #include #include #include using namespace std; const int N = 1e5 + 10, M = N << 1; //邻接表 int e[M], h[N], idx, ne[M]; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } // dfs序专用数据结构 int in[N], out[N], tot; // dfs序模板 void dfs(int u, int fa) { in[u] = ++tot; // dfs序中u节点进入 时间戳 for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (j == fa) continue; //不走回头路 dfs(j, u); } out[u] = tot; // dfs序中u节点退出 时间戳 } //线段树结构体 struct Node { int l, r; int sum; } tr[N << 2]; //向上更新父节点的子树苹果和 void pushup(int u) { tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum; } //构建线段树 void build(int u, int l, int r) { tr[u] = {l, r}; if (l == r) { tr[u].sum = 1; //最初的时候每个叶子节点上都是有苹果的 return; } int mid = (l + r) >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); //向上更新父节点信息 pushup(u); } //在以u为根的子树中修改x的值 void modify(int u, int x) { if (tr[u].l == tr[u].r) { tr[u].sum ^= 1; //异或就是将1变0,将0变1。 return; } int mid = (tr[u].l + tr[u].r) >> 1; if (x <= mid) modify(u << 1, x); else modify(u << 1 | 1, x); pushup(u); } //查询区间值 int query(int u, int l, int r) { if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum; int mid = (tr[u].l + tr[u].r) >> 1; int ans; if (r <= mid) ans = query(u << 1, l, r); else if (l > mid) ans = query(u << 1 | 1, l, r); else ans = query(u << 1, l, r) + query(u << 1 | 1, l, r); return ans; } int main() { int n, m; scanf("%d", &n); memset(h, -1, sizeof h); for (int i = 1; i < n; i++) { int a, b; scanf("%d%d", &a, &b); add(a, b), add(b, a); } //记录dfs序 dfs(1, 0); //构建线段树 build(1, 1, n); scanf("%d", &m); while (m--) { char op[2]; //注意:一般字符都需要用char数组读入,可以过滤掉空格和回车 int k; scanf("%s%d", op, &k); //注意op按字符数组读入是不用&地址符的! if (*op == 'C') modify(1, in[k]); //原始第k个节点,对应线段树中第in[k]个节点 else printf("%d\n", query(1, in[k], out[k])); //查询k这个点在in[k],out[k]区间内的sum和。 } return 0; }