有一顆樹,開始每一個點的值都是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]));//輸出
}
}
}