题意:
给一棵nn个节点的树,每个节点开始有一个苹果,mm次操作
1.将某个结点的苹果数异或 11
2.查询一棵子树内的苹果数

树上的修改查询要转化成线性的话,用的方法就是DFS序

对于每个节点xx 第一次出现和第二次出现的区间的数便是xx的子树
那么我们用DFS序转成线性区间后用树状数组维护即可

#include <iostream>
#include <cstdio>
#include <cstring>
#define pa pair<int, int>
#define mp make_pair
#define lowbit(x) ((x)&(-x))
#define mem(i, a) memset(i, a, sizeof(i))
#define sqr(x) ((x)*(x))
#define ls (k << 1)
#define rs (k << 1 | 1)
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int N = 1e5 + 5;
int n;
struct edge {
    int u,v,next;
}e[N << 1];
int st[N],en[N],q[N],a[N],id,head[N],cnt;
struct binary {
    int c[N << 1];
    void clear() {mem(c, 0);}

    void update(int p, int x) {
        for(int i = p; i <= n; i += lowbit(i)) 
            c[i] += x;
    }
    int query(int x) {
        int ans = 0;
        for(int i = x; i ; i -= lowbit(i))
            ans += c[i];
        return ans;
    }
    int ask(int l, int r) {
        return query(r) - query(l - 1);
    }
}tr;
void insert(int u, int v) {
    e[++cnt].u = u; e[cnt].v = v; e[cnt].next = head[u]; head[u] = cnt;
}
void dfs(int u, int fa) {
    q[++id] = u;
    st[u] = id;
    for(int i = head[u]; i ; i = e[i].next) {
        int v = e[i].v;
        if(v != fa) dfs(v, u);
    }
    en[u] = id;
}
int main() {
#ifdef INCTRY
    freopen("input.txt", "rt", stdin);
#endif

    cin >> n;
    tr.clear();
    for(int i = 1; i <= n - 1; i++) {
        int u,v;
        scanf("%d %d", &u, &v);
        insert(u, v); insert(v, u);
    }
    dfs(1, -1);
    for(int i = 1; i <= n; i++) {
        tr.update(i, 1); a[i] = 1;
    }
    int m; 
    cin >> m;
    for(int i = 1; i <= m; i++) {
        char c;
        int x;
        cin >> c >> x;
        if(c == 'Q') {
            printf("%d\n", tr.ask(st[x], en[x]));
        } else {
            int p = a[x] == 1 ? -1 : 1;
            a[x] ^= 1;
            tr.update(st[x], p);
        }
    }
    return 0;
}