有一颗树,开始每一个点的值都是1,有两种操做:
1.将一个点的值取反
2.询问一个子树的值的和css
用后续遍历就能够作到用一个区间表明一棵子树。而后用线段树就行了。markdown
#include<cstdio>
using namespace std;
struct line{
int to,next;
}a[100001];
int tot,x,y,num[100001],c[100001],ls[100001],m;
int n,begin[100001],mark[100001];
bool apple[100001];
char cc;
void dfs(int x)
{
begin[x]=tot;
for (int q=ls[x];q;q=a[q].next)
{
dfs(a[q].to);
}
mark[x]=++tot;
}//深搜求后序遍历
int lowbit(int x)
{return x&(-x);}
void change(int x,int num)//改变
{
int i=x;
while(i<=n)
{
c[i]+=num;
i+=lowbit(i);
}
}
int getsum(int x)//求和
{
int sum=0;
while (x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<n;i++)
{
scanf("%d%d",&x,&a[i].to);
a[i].next=ls[x];
ls[x]=i;//插入边
change(i,1);//改值
}
change(n,1);
dfs(1);//后序遍历
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("\n%c %d",&cc,&x);
if (cc=='C')
{
apple[x]=!apple[x];
if (apple[x])
change(mark[x],-1);
else
change(mark[x],1);//该值取反
}
else
{
printf("%d\n",getsum(mark[x])-
getsum(begin[x]));//输出
}
}
}