TmonoのACM
坚持是一种饼~

思路:用邻接表存图,卡vector【这里被卡哭了QAQ】,用dfs遍历的顺序重新给节点编号,遍历时记录儿子数目。用dfs序建立线段树,change的时候单点更新,查询某子树上的苹果树即是查询该节点[i, i+childnum]这个区间的苹果数目,i指dfs序。

 总结:邻接表出边入边傻傻搞不清楚QAQ

AC代码:

  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 */
View Code

 

posted on 2014-09-09 16:15  Pobo_biu  阅读(218)  评论(0编辑  收藏  举报