标签:
参考来源: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