标签:
参考来源: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 100010 int 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; }
标签:
原文地址:http://www.cnblogs.com/subrshk/p/4238543.html