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
"C 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
"Q 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
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; }
- POJ 3321 Apple Tree
- POJ 3321 Apple Tree
- poj 3321 Apple Tree
- POJ 3321 Apple Tree
- Poj 3321 Apple Tree
- poj 3321 apple tree
- poj 3321 Apple Tree
- poj 3321 Apple Tree
- POJ 3321 Apple Tree
- POJ--3321--Apple Tree
- POJ-3321-Apple Tree
- poj 3321 Apple Tree
- POJ 3321 Apple Tree
- POJ 3321 Apple Tree
- POJ 3321 Apple Tree
- POJ 3321 Apple Tree
- POJ:3321 Apple Tree
- POJ 3321 Apple Tree
- Ubuntu常用快捷键
- 语音编解码器
- KMP的原理和代码实现(详细注释|参考多个博客总结|可作为模板)
- C语言:编写函数reverse(s)将字符串s中的字符顺序颠倒过来。
- 《Linux》天影linux系列笔记一——linux常用命令详解:whereis
- POJ 3321 apple tree
- 关于MFC未来的感悟
- Java读取Oracle数据库并解析成XML文件
- DNS无法解析域名,ARP无法解析 (arp欺骗)解决方法
- Cocos2d-x PluginX (二)增加新的Plugin
- app-framework学习--官网地址及demo下载地址
- Eclipse常用快捷键
- 《Linux》天影linux系列笔记一——linux常用命令详解:wc
- 函数指针和指针函数