先确定节点关系,使每个节点都用一个线段表示,begin表示起始位置,end表示结束位置在树上搜索确定。然后就是纯树状数组模板了。
这道题卡vector最好不用。
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100005
struct TNode
{
int to,next;
}nod[2*N];
int n,m,edges;
bool apple[N],vis[N];
int f[N],cal[N],begin[N],end[N];
void addedge(int u,int v)
{
nod[edges].to=v;
nod[edges].next=f[u];
f[u]=edges++;
}
void dfs(int u)
{
edges++;
begin[u]=edges;
vis[u]=1;
for(int i=f[u];i!=-1;i=nod[i].next)
{
if(!vis[nod[i].to])
dfs(nod[i].to);
}
end[u]=edges;
}
int lowbit(int x) {return x&(-x);}
int getsum(int x)
{
int s=0;
for(;x>0;x-=lowbit(x)) s+=cal[x];
return s;
}
void update(int x,int value)
{
for(;x<=n;x+=lowbit(x)) cal[x]+=value;
}
int main()
{
int i,u,v;
char str[5];
scanf("%d",&n);
memset(f,-1,sizeof(f));
memset(vis,0,sizeof(vis));
memset(apple,1,sizeof(apple));
edges=0;
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
edges=0;
dfs(1);
for(i=1;i<=n;i++) update(i,1);
scanf("%d",&m);
while(m--)
{
scanf("%s%d",str,&u);
if(str[0]=='C')
{
if(apple[u])
{
update(begin[u],-1);
apple[u]=0;
}
else
{
update(begin[u],1);
apple[u]=1;
}
}
else printf("%d\n",getsum(end[u])-getsum(begin[u]-1));
}
return 0;
}