题目:http://poj.org/problem?id=3321
题意:给出一个苹果树,开始每个节点都有一个苹果,有2个操作
C:有苹果就吃掉,没有就会长出一个苹果
Q:查询包括x的子树上苹果的个数
这个题目的关键就是怎么把它从一颗树转化成一个数组
可以用dfs序重新编号,保存节点所维护的区间,然后用树状数组可以解决了
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; const int N=1e5+5; struct p { int to,nextt; }; p a[N*2]; int tot,n; int f[N],l[N],r[N],bit[N]; bool vis[N]; void addedge(int u,int v) { a[tot].to=v; a[tot].nextt=f[u]; f[u]=tot++; } void dfs(int x) { tot++; l[x]=tot; vis[x]=1; for(int i=f[x];i!=-1;i=a[i].nextt) if (!vis[a[i].to]) dfs(a[i].to); r[x]=tot; } void add(int i,int x) { while(i<=n) { bit[i]+=x; i+=i&-i; } } int sum(int i) { int s=0; while(i>0) { s+=bit[i]; i-=i&-i; } return s; } int main() { while(scanf("%d",&n)!=EOF) { int x,y; tot=0; memset(f,-1,sizeof(f)); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } tot=0; memset(vis,0,sizeof(vis)); dfs(1); memset(bit,0,sizeof(bit)); for(int i=1;i<=n;i++) add(i,1); memset(vis,1,sizeof(vis)); int m; char c; scanf("%d",&m); while(m--) { scanf(" %c%d",&c,&x); if (c=='Q') printf("%d ",sum(r[x])-sum(l[x]-1)); else { if (vis[x]) { vis[x]=0; add(l[x],-1); } else { vis[x]=1; add(l[x],1); } } } } return 0; }