POJ 3321 apple tree

来源:互联网 发布:手机版淘宝店入驻申请 编辑:程序博客网 时间:2024/06/05 08:12

Description

There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree.

The tree has N forks which are connected by branches. Kaka numbers the forks by 1 to N and the root is always numbered by 1. Apples will grow on the forks and two apple won't grow on the same fork. kaka wants to know how many apples are there in a sub-tree, for his study of the produce ability of the apple tree.

The trouble is that a new apple may grow on an empty fork some time and kaka may pick an apple from the tree for his dessert. Can you help kaka?

Input

The first line contains an integer N (N ≤ 100,000) , which is the number of the forks in the tree.
The following N - 1 lines each contain two integers u and v, which means fork u and fork v are connected by a branch.
The next line contains an integer M (M ≤ 100,000).
The following M lines each contain a message which is either
"x" which means the existence of the apple on fork x has been changed. i.e. if there is an apple on the fork, then Kaka pick it; otherwise a new apple has grown on the empty fork.
or
"x" which means an inquiry for the number of apples in the sub-tree above the fork x, including the apple (if exists) on the fork x
Note the tree is full of apples at the beginning

Output

For every inquiry, output the correspond answer per line.

Sample Input

31 21 33Q 1C 2Q 1

Sample Output

32

题意:一棵树上有n个叉子(其实就是n个节点),再告诉你n-1个线段告诉你是u和v节点相连的,再输入m组操作,有两种操作,当是Q操作时你就要输出对象的节点上有多少个苹果(初始化时每个节点都有苹果),C操作是吃掉苹果或是长出苹果(一个节点只能是有一个苹果或是没有苹果,即:有苹果就是吃掉当前节点的苹果,没苹果就是长出苹果)。

思路:可以把它倒过来就可以用树状数组做了,就是还要用dfs来搜一下每个节点的分支有多少个,开始的时间和结束的时间就可以了。

AC代码:

#include<cstdio>  #include<cstring>  #include<iostream>  using namespace std;  const int maxn=100005;  struct node1  {      int next;      int tail;  }edge[maxn];      //这结构体是表示第i条边的下一条边的编号和这条边所连的节点  struct node2  {      int l,r;  }apple[maxn];     //苹果树表示i节点的开始时间个终止时间  int s[maxn],cnt,c[maxn],a[maxn];   //s存储的是i节点的分支数,cnt是总共的节点数,c数组是树状数组,a是树状数组的每个节点的权值(1或是0)  void dfs(int u)  {      int i;      apple[u].l=cnt;      for(i=s[u];i!=-1;i=edge[i].next)          dfs(edge[i].tail);      apple[u].r=cnt++;  }  int lowbit(int x)  {      return x&(-x);  }  void change(int x)  {      int i;      if(a[x])          for(i=x;i<cnt;i+=lowbit(i))          c[i]++;      else          for(i=x;i<cnt;i+=lowbit(i))          c[i]--;  }  int sum(int x)  {      int res=0;      while(x)      {          res+=c[x];          x-=lowbit(x);      }      return res;  }  int main()  {      int n,m,t1,t2,t;      char str[5];      scanf("%d",&n);      memset(s,-1,sizeof(s));      memset(apple,0,sizeof(apple));      memset(c,0,sizeof(c));      for(int i=0;i<n-1;i++)      {          scanf("%d%d",&t1,&t2);          edge[i].tail=t2;          edge[i].next=s[t1];          s[t1]=i;      }      cnt=1;      dfs(1);      scanf("%d",&m);      for(int i=1;i<=n;i++)     //初始化每个节点的权值都是1      {          a[i]=1;          change(i);      }      while(m--)      {          scanf("%s%d",&str,&t);          if(str[0]=='Q')              printf("%d\n",sum(apple[t].r)-sum(apple[t].l-1));          else          {              a[apple[t].r]=(a[apple[t].r]+1)%2;    //权值只能是0和1   所以对2取余              change(apple[t].r);          }      }      return 0;  }  


0 0
原创粉丝点击