標籤:
參考來源:http://www.cnblogs.com/frog112111/p/3269281.html
/**POJ 3321 樹狀數組 + DFS*題意:一棵蘋果樹,有n個節點,每個節點上有或僅有1個蘋果,初始時每個節點上都有蘋果* 給出n-1個節點間關係* m次操作:* C x 若x節點有蘋果,則摘下,若沒有,則會長出一個* Q x 詢問x節點以下的所有節點的蘋果數之和*//*DFS求每個節點的第一次訪問時間和最後的訪問時間,*則begin[x] 和 end[x] 之間的節點就是x的子樹*剩下的就是用樹狀數組求 getSum(end[u]) - getSum(begin[u] - 1)*/#include <cstdio>#define lowbit(x) x&(-x)#define MAXN 100010int c[MAXN], n;int first[MAXN]; //記錄鄰接表的前端節點的編號int begin[MAXN]; //每個節點的起始時間int end[MAXN]; //每個節點的結束時間bool has[MAXN]; //記錄節點上是否有蘋果int count;void update(int x, int val){for (int i = x; i <= n; i += lowbit(i)) {c[i] += val;}}int getSum(int x){int sum = 0;for (int i = x; i > 0; i -= lowbit(i)) {sum += c[i];}return sum;}struct edge {int v, next;} edge[MAXN]; //記錄邊的資訊void insert(int u, int v){edge[count].v = v;edge[count].next = first[u];first[u] = count++;}void dfs(int x){begin[x] = ++ count;for (int i = first[x]; i != -1; i = edge[i].next) {dfs(edge[i].v);}end[x] = count;}int main(){int u, v, m, ans;char s[10];scanf("%d", &n);count = 0;for (int i = 0; i <= MAXN; i++) {first[i] = -1;}for (int i = 0; i < n - 1; i ++) {scanf("%d %d", &u, &v);insert(u, v);}count = 0;dfs(1);// for(int i = 0; i < n; i++){// printf("%d %d %d %d %d\n",first[i], begin[i], end[i], edge[i].v, edge[i].next);// }for (int i = 1; i <= n; i++) {update(i, 1);has[i] = true;}scanf("%d", &m);while (m--) {scanf("%s %d", s, &u);if (s[0] == ‘Q‘) {printf("%d\n", getSum(end[u]) - getSum(begin[u] - 1));} else {if (has[u]) {update(begin[u], -1);} else {update(begin[u], 1);}has[u] = !has[u];}}return 0;}
POJ 3321 Apple Tree