思路:用邻接表存图,卡vector【这里被卡哭了QAQ】,用dfs遍历的顺序重新给节点编号,遍历时记录儿子数目。用dfs序建立线段树,change的时候单点更新,查询某子树上的苹果树即是查询该节点[i, i+childnum]这个区间的苹果数目,i指dfs序。
总结:邻接表出边入边傻傻搞不清楚QAQ
AC代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 #define maxn 200010 8 #define lson l, m, rt<<1 9 #define rson m+1, r, rt<<1|1 10 struct node 11 { 12 int cnt, val, num; 13 }; 14 int n, m; 15 node arr[maxn]; 16 int u[maxn], v[maxn], next[maxn], first[maxn]; 17 bool vis[maxn]; 18 int sgt[maxn<<2]; 19 void init() 20 { 21 memset(vis, 0, sizeof(vis)); 22 for(int i = 0; i < n+10; i++) first[i] = -1; 23 int e = 0, i; 24 for(i = 1; i < n; i++) { 25 scanf("%d%d", &u[i], &v[i]); 26 next[i] = first[u[i]]; 27 first[u[i]] = i; 28 u[n-1+i] = v[i]; 29 v[n-1+i] = u[i]; 30 next[n-1+i] = first[u[n-1+i]]; 31 first[u[n-1+i]] = n-1+i; 32 } 33 } 34 int dfs(int i, int &num) 35 {//cout<<i<<" - "<<num<<endl; 36 arr[i].val = 1; 37 arr[i].cnt = 0; 38 arr[i].num = num; 39 vis[i] = 1; 40 for(int j = first[i]; j != -1; j = next[j]) { 41 if(!vis[v[j]]) { num++; arr[i].cnt += dfs(v[j], num); } 42 } 43 return arr[i].cnt+1; 44 } 45 void push_up(int rt) 46 { 47 sgt[rt] = sgt[rt<<1] + sgt[rt<<1|1]; 48 } 49 void build(int l, int r, int rt) 50 { 51 sgt[rt] = 1; 52 if(l == r) return; 53 int m = (r+l)>>1; 54 build(lson); 55 build(rson); 56 push_up(rt); 57 } 58 void change(int l, int r, int rt, int pos) 59 { 60 if(l == r) { 61 if(sgt[rt] == 1) sgt[rt] = 0; 62 else sgt[rt] = 1; 63 return; 64 } 65 int m = (r+l)>>1; 66 if(pos <= m) change(lson, pos); 67 else change(rson, pos); 68 push_up(rt); 69 } 70 int query(int l, int r, int rt, int L, int R ) 71 { 72 if(L <= l && r <= R) { 73 return sgt[rt]; 74 } 75 int res = 0; 76 int m = (l+r)>>1; 77 if(L <= m) res += query(lson, L, R); 78 if(m < R) res += query(rson, L, R); 79 return res; 80 } 81 void work() 82 { 83 if(n == 1) { 84 int x = 1; 85 scanf("%d", &m); 86 char re; int k; 87 while (m--) { 88 getchar(); 89 scanf("%c%d", &re, &k); 90 if(re == 'Q') { 91 printf("%d\n", x); 92 } 93 else { 94 if(x == 0) x = 1; else x = 0; 95 } 96 } 97 }else { 98 init(); 99 int xxx = 1; 100 dfs(1,xxx); 101 build(1, n, 1); 102 char re; int k; 103 scanf("%d", &m); 104 for (int i = 0; i < m; i++) { 105 getchar(); 106 scanf("%c%d", &re, &k); 107 if(re == 'C') { 108 change(1, n, 1, arr[k].num); 109 } 110 else { 111 int res = query(1, n, 1, arr[k].num, arr[k].num+arr[k].cnt); 112 printf("%d\n", res); 113 } 114 } 115 } 116 } 117 int main() 118 { 119 while(scanf("%d", &n) != EOF && n) work(); 120 return 0; 121 } 122 /* 123 7 124 1 3 125 1 4 126 3 5 127 3 6 128 4 2 129 4 7 130 11 131 Q 2 132 Q 2 133 Q 1 134 C 3 135 Q 3 136 C 3 137 Q 3 138 C 4 139 Q 7 140 Q 4 141 Q 2 142 143 */