先確定節點關係,使每個節點都用一個線段表示,begin表示起始位置,end表示結束位置在樹上搜尋確定。然後就是純樹狀數組模板了。
這道題卡vector最好不用。
#include<cstdio>#include<vector>#include<cstring>#include<algorithm>using namespace std;#define N 100005struct 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;}