POJ 3321:Apple Tree 树状数组
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 22131 | Accepted: 6715 |
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
3
1 2
1 3
3
Q 1
C 2
Q 1
Sample Output
3
2
题意是有一个树,树根始终是1。最开始每一个节点上都上有苹果,然后就开始折腾了。
操作为Q时是询问,该分叉上现在一共有多少个苹果。
操作为C时,如果当前该节点上有苹果,摘掉。如果当前该节点没有苹果,长出一个来。
先dfs出每一个节点的起始时间和结束时间,然后根据起始时间和结束时间使用树状数组求和的思想就能得到结果。
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; #define MY_MAX 220000
int C[MY_MAX];
vector<vector<int>> G(MY_MAX/2);
int HasApple[MY_MAX/2];
int sta[MY_MAX];
int en[MY_MAX];
int ncount=0;
int n,m; void dfs(int v)
{
sta[v] = ++ncount;
for(int i=0;i<G[v].size();i++)
{
dfs(G[v][i]);
}
en[v] = ++ncount;
} int lowbit(int x)
{
return x&(-x);
} void add(int x,int val)
{
while(x<=en[1]+1)
{
C[x] = C[x] + val;
x=x+lowbit(x);
}
} int sum(int x)
{
int res=0;
while(x>0)
{
res+=C[x];
x=x-lowbit(x);
}
return res;
}
int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); int i,temp1,temp2;
char oper[5]; scanf("%d",&n);
for(i=1;i<=n-1;i++)
{
scanf("%d%d",&temp1,&temp2);
G[temp1].push_back(temp2);
HasApple[i]=1;
}
HasApple[n]=1;
dfs(1);
scanf("%d",&m);
memset(C,0,sizeof(C));
for(i=1;i<=en[1]+1;i++)
{
add(i,1);
}
for(i=1;i<=m;i++)
{
scanf("%s%d",oper,&temp1);
if(oper[0]=='C')
{
if(HasApple[temp1])
{
HasApple[temp1]=0;
add(sta[temp1]+1,-1);
add(en[temp1]+1,-1);
}
else
{
HasApple[temp1]=1;
add(sta[temp1]+1,1);
add(en[temp1]+1,1);
}
}
else if(oper[0]=='Q')
{
printf("%d\n",(sum(en[temp1])-sum(sta[temp1]))/2+HasApple[temp1]);
}
} //system("pause");
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 3321:Apple Tree 树状数组的更多相关文章
- POJ 3321 Apple Tree(树状数组)
Apple Tree Time Limit: 2000MS Memory Lim ...
- POJ 3321 Apple Tree (树状数组+dfs序)
题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...
- POJ 3321 Apple Tree 树状数组+DFS
题意:一棵苹果树有n个结点,编号从1到n,根结点永远是1.该树有n-1条树枝,每条树枝连接两个结点.已知苹果只会结在树的结点处,而且每个结点最多只能结1个苹果.初始时每个结点处都有1个苹果.树的主人接 ...
- POJ 3321 Apple Tree 树状数组 第一题
第一次做树状数组,这个东西还是蛮神奇的,通过一个简单的C数组就可以表示出整个序列的值,并且可以用logN的复杂度进行改值与求和. 这道题目我根本不知道怎么和树状数组扯上的关系,刚开始我想直接按图来遍历 ...
- 3321 Apple Tree 树状数组
LIANJIE:http://poj.org/problem?id=3321 给你一个多叉树,每个叉和叶子节点有一颗苹果.然后给你两个操作,一个是给你C清除某节点上的苹果或者添加(此节点上有苹果则清除 ...
- POJ--3321 Apple Tree(树状数组+dfs(序列))
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 22613 Accepted: 6875 Descripti ...
- E - Apple Tree(树状数组+DFS序)
There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...
- POJ3321 Apple Tree(树状数组)
先做一次dfs求得每个节点为根的子树在树状数组中编号的起始值和结束值,再树状数组做区间查询 与单点更新. #include<cstdio> #include<iostream> ...
- POJ 2486 Apple Tree [树状DP]
题目:一棵树,每个结点上都有一些苹果,且相邻两个结点间的距离为1.一个人从根节点(编号为1)开始走,一共可以走k步,问最多可以吃多少苹果. 思路:这里给出数组的定义: dp[0][x][j] 为从结点 ...
随机推荐
- freemarker 作为 word 模板实现下载功能
1:新建一个.doc 文档写好自己要导出文字如下图 2:把word 文档另存为xml 格式的文件用编辑器打开如图下,(如果你打开文件里面的标签没换行格式,那么你在myeclipse 新建一个jsp 文 ...
- 页面自动执行js的3种方法
1.最简单的调用方式,直接写到html的body标签里面: <html> <body onload="load();"> </body> & ...
- 字典NSDictionary和NSMutableDictionary的使用
简介:字典是一种数据结构,字典里面的每一个元素,是一个key-value(键值对),key和value都是对象类型.同NSArray一样,里面的对象不用保持一致性. NSDictionary 1.字面 ...
- Vuex踩坑--数据刷新时丢失
近期做项目的过程中,使用vuex保存页面公共数据,测试无网情况后又接通网络的情况下,页面进行重新加载.遇到一个小bug——发现在苹果手机IOS系统下,页面刷新重新加载后页面中通过vuex存储并显示的数 ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:安装zookeeper集群
实验目的 了解zookeeper的概念和原理 学会安装zookeeper集群并验证 掌握zookeeper命令使用 实验原理 1.Zookeeper介绍 ZooKeeper是一个分布式的,开放源码的分 ...
- 【剑指Offer面试编程题】题目1366:栈的压入、弹出序列--九度OJ
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...
- Xshell 5的快捷键
Xshell 5的快捷键 1. 点击下图中的按钮查看快捷键: 2. 快捷键备忘录: 序号 功能 快捷键 备注 1 在窗口和撰写栏之间切换 Alt+I 2 全屏 Alt+Enter 3 ...
- Linux CentOS7 VMware 相对和绝对路径、cd命令、mkdir/rmdir、rm命令——笔记
一. 相对和绝对路径 绝对路径是从/(也被称为根目录)开始的,比如/usr.cd /root/ pwd 注:判断用户当前所处的位置 相对路径是以 . 或 .. 开始的 二.cd命令 cd 是进入到当前 ...
- linux零散知识
1.Linux的“| ”管道符用法 上一条命令的输出,作为下一条命令参数 方式:command1 | command2 Linux所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符 ...
- 在linux环境中如何删除文件
使用rm -rf 目录名字 命令即可 -r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 eg 删除文件夹实例:rm -rf /var/log/httpd/acc ...