【POJ3321】Apple Tree-DFS+树状数组维护
题目大意:有一棵树有n个节点,刚开始每个节点的权值都为1,有两种操作:1.修改某一个节点的权值,把1修改成0,把0修改成1。2.询问以某一个节点为根的子树上的点的权值之和。对于每一个询问,给出正确的答案。
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,tot,first[100010]={0},c[100010]={0};
int begin[100010]={0},end[100010]={0};
bool v[100010]={0};
struct edge
{
int v,next;
}e[200010];
void insert(int a,int b)
{
e[++tot].v=b;
e[tot].next=first[a];
first[a]=tot;
}
void dfs(int x)
{
v[x]=1;
begin[x]=tot;
for(int i=first[x];i>0;i=e[i].next)
if (!v[e[i].v]) {++tot;dfs(e[i].v);}
end[x]=tot;
}
int lowbit(int i)
{
return i&(-i);
}
void add(int x,int a)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=a;
}
int sum(int x)
{
int s=0;
for(int i=x;i>0;i-=lowbit(i))
s+=c[i];
return s;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d %d",&a,&b);
insert(a,b);insert(b,a);
}
for(int i=1;i<=n;i++) add(i,1);
tot=1;
dfs(1);
scanf("%d\n",&m);
for(int i=1;i<=m;i++)
{
char op;int p;
scanf("%c %d\n",&op,&p);
if (op=='C')
{
int s=sum(begin[p])-sum(begin[p]-1);
if (s) add(begin[p],-1);
else add(begin[p],1);
}
else printf("%d\n",sum(end[p])-sum(begin[p]-1));
}
return 0;
}