首先这不一定是一个二叉树,用线段树的话并不好搞。
为什么会用到树状数组呢?因为在树状数组上查询和更改方便而且是n(logn)。
查询一个子树的和就相当于这些数相加。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 150005
typedef long long ll;
struct node
{
ll to,next;
}edge[inf<<1];
ll cnt;
ll head[inf<<1];
void add(ll f,ll t)
{
edge[cnt].to=t;
edge[cnt].next=head[f];
head[f]=cnt++;
}
ll n,m;
ll sta[inf];
ll start[inf],ending[inf];
ll scc;
int vis[inf];
void init(ll st)
{
scc++;
sta[st]=1;
start[st]=scc;
vis[st]=1;
for(ll i=head[st];i!=-1;i=edge[i].next)
{
ll to=edge[i].to;
if(vis[to]==1)continue;
init(to);
}
ending[st]=scc;
}
char s[5];
ll sum[inf<<2];
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll x,ll ad)
{
while(x<=n)
{
sum[x]+=ad;
x+=lowbit(x);
}
}
ll quary(ll x)
{
ll ss=0;
while(x)
{
ss+=sum[x];
x-=lowbit(x);
}
return ss;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%lld",&n);
if(n==0)return 0;
for(ll i=1;i<n;i++)
{
ll a,b;
scanf("%lld %lld",&a,&b);
add(a,b);
add(b,a);
}
init(1);
for(ll i=1;i<=n;i++)
{
update(i,1);
}
scanf("%lld",&m);
while(m--)
{
ll num;
scanf("%s %lld",s,&num);
if(s[0]=='C')
{
if(sta[num]==1)
{
update(start[num],-1);
sta[num]=0;
}else
{
update(start[num],1);
sta[num]=1;
}
}else
{
printf("%lld\n",quary(ending[num])-quary(start[num]-1));
}
}
}