【DFS序+单点修改区间求和】POJ 3321 Apple Tree

poj.org/problem?id=3321

【题意】

给一棵n个节点的树,每个节点开始有一个苹果,m次操作
1.将某个结点的苹果数异或 1
2.查询一棵子树内的苹果数
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<cmath>
  6 #include<algorithm>
  7 using namespace std;
  8 typedef long long ll;
  9 
 10 const int maxn=1e5+2;
 11 const int maxm=2*maxn;
 12 int n;
 13 struct edge
 14 {
 15     int to;
 16     int nxt;
 17 }e[maxm];
 18 int head[maxn];
 19 int tot;
 20 int l[maxn],r[maxn];
 21 int tree[maxm];
 22 bool vis[maxn];
 23 int cid;
 24 int lowbit(int x)
 25 {
 26     return x&(-x);
 27 }
 28 
 29 void add(int k,int x)
 30 {
 31     while(k<=cid)//注意是cid,不是n 
 32     {
 33         tree[k]+=x;
 34         k+=lowbit(k);
 35     }
 36 }
 37 
 38 int query(int k)
 39 {
 40     int ans=0;
 41     while(k)
 42     {
 43         ans+=tree[k];
 44         k-=lowbit(k);
 45     }
 46     return ans;
 47 }
 48 void init()
 49 {
 50     memset(head,-1,sizeof(head));
 51     tot=0;
 52     cid=0;
 53     memset(vis,false,sizeof(vis));
 54 }
 55 
 56 void addedge(int u,int v)
 57 {
 58     e[tot].to=v;
 59     e[tot].nxt=head[u];
 60     head[u]=tot++;
 61 }
 62 
 63 void dfs(int u,int pa)
 64 {
 65     l[u]=++cid;
 66     for(int i=head[u];i!=-1;i=e[i].nxt)
 67     {
 68         int v=e[i].to;
 69         if(v==pa) continue;
 70         dfs(v,u);    
 71     }    
 72     r[u]=++cid;
 73 }
 74 
 75 int main()
 76 {
 77     while(~scanf("%d",&n))
 78     {
 79         init();
 80         int u,v;
 81         for(int i=1;i<=n-1;i++)
 82         {
 83             scanf("%d%d",&u,&v);
 84             addedge(u,v);
 85             addedge(v,u);
 86         }
 87         dfs(1,-1);
 88         for(int i=1;i<=n;i++)
 89         {
 90             add(l[i],1);//单点修改 
 91         }    
 92         int q;
 93         scanf("%d",&q);
 94         char str[2];
 95         int x;
 96         while(q--)
 97         {
 98             scanf("%s%d",str,&x);
 99             if(str[0]=='Q')
100             {
101                 int ans=query(r[x])-query(l[x]-1);
102                 printf("%d\n",ans);
103             }
104             else
105             {
106                 if(!vis[x])
107                 {
108                     add(l[x],-1);
109                     vis[x]=true;
110                 }
111                 else
112                 {
113                     add(l[x],1);
114                     vis[x]=false;
115                 }
116             }
117         }
118     }
119     return 0;
120  } 
View Code

 

posted @ 2017-08-23 15:05  shulin15  阅读(175)  评论(0编辑  收藏  举报