POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
题意分析
卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果。卡卡很喜欢苹果。树上有N个节点,卡卡给他们编号1到N,根的编号永远是1.每个节点上最多结一个苹果。卡卡想要了解某一个子树上一共结了多少苹果。
现在的问题是不断会有新的苹果长出来,卡卡也随时可能摘掉一个苹果吃掉。你能帮助卡卡吗?
前缀技能
边表存储树
DFS时间戳
线段树
首先利用边表将树存储下来,然后DFS打上时间戳。打上时间戳之后,我们就知道书上节点对应维护线段树的哪一段区间了。换句话说,每当题目给出一个点,要求更新的时候,我们根据时间戳,确定其点在线段树上的位置。当题目给出一个区间,要求我们查询的时候,再根据时间戳,确定线段树区间左右端点。如此一来,就可以将树上信息,转换到线段树上来维护。
注意
- 值得注意的是,我的边表存的是两条边,所以边表的容量要开二倍。
- 其次就是,无论在更新的时候,还是在查询的时候,要根据时间戳,转化到线段树的对应点或者区间上。因为这个WA了。
代码总览
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define nmax 100010
using namespace std;
struct edge{
int to,next;
}edg[nmax<<1];
struct Tree{
int l,r,val;
int mid(){
return (l+r)>>1;
}
};
Tree tree[nmax<<2];
int head[nmax],in[nmax],out[nmax];
int tot = 0,n,m,time = 0;
void add(int u, int v){
edg[tot].to = v;
edg[tot].next = head[u];
head[u] = tot++;
}
void init(){
memset(head,-1,sizeof head);
memset(edg, 0, sizeof edg);
memset(tree,0,sizeof tree);
memset(in,0,sizeof in);
memset(out ,0, sizeof out);
tot= 0;
time = 0;
}
void dfs(int rt,int f){
time++;
in[rt] = time;
for(int i = head[rt]; i!= -1;i= edg[i].next){
int net = edg[i].to;
if(net != f) dfs(net,rt);
}
out[rt] = time;
}
void PushUp(int rt)
{
tree[rt].val = tree[rt<<1].val + tree[rt<<1|1].val;
}
void Build(int l, int r, int rt)
{
tree[rt].l = l; tree[rt].r = r;
if(l == r){
tree[rt].val = 1;
return;
}
Build(l,tree[rt].mid(),rt<<1);
Build(tree[rt].mid()+1,r,rt<<1|1);
PushUp(rt);
}
void UpdatePoint(int pos, int rt)
{
if(tree[rt].l == tree[rt].r){
tree[rt].val ^= 1;
return;
}
if(pos<= tree[rt].mid()) UpdatePoint(pos,rt<<1);
else UpdatePoint(pos,rt<<1|1);
PushUp(rt);
}
int Query(int l,int r,int rt)
{
if(l>tree[rt].r || r<tree[rt].l) return 0;
if(l <= tree[rt].l && tree[rt].r <= r) return tree[rt].val;
return Query(l,r,rt<<1) + Query(l,r,rt<<1|1);
}
int main()
{
while(scanf("%d",&n) != EOF){
init();
int u,v;
for(int i = 0;i<n-1;++i){
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,0);
Build(1,n,1);
int m;scanf("%d",&m);
char op;int x;
for(int i = 0;i<m;++i){
scanf(" %c %d",&op,&x);
if(op == 'Q'){
printf("%d\n",Query(in[x],out[x],1));
}else{
UpdatePoint(in[x],1);
}
}
}
return 0;
}
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)的更多相关文章
- poj 3321 Apple Tree dfs序+线段树
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Description There is an apple tree outsid ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- hdu 1166线段树 单点更新 区间求和
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu1166(线段树单点更新&区间求和模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:中文题诶- 思路:线段树单点更新,区间求和模板 代码: #include <iost ...
- POJ 3321 Apple Tree DFS序 + 树状数组
多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...
- POJ3321 - Apple Tree DFS序 + 线段树或树状数组
Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- POJ 3321 Apple Tree DFS序+fenwick
题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思 ...
随机推荐
- 基于Neutron的Kubernetes SDN实践经验之谈
首先,向大家科普下Kubernetes所选择的CNI网络接口,简单介绍下网络实现的背景. CNI即Container Network Interface,是一套容器网络的定义规范,包括方法规范.参数规 ...
- java后端面试题汇总
转载链接:https://www.nowcoder.com/discuss/90776?type=0&order=0&pos=23&page=0 基础篇 数据结构与算法 线性表 ...
- 在 Linux 下执行安装 bin 文件
原文: http://www.linuxidc.com/Linux/2014-03/98541.htm
- “Hello World!”团队第六周第七次会议
博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.checkout&push代码 一.会议时间 2017年11月23日 ...
- Daily Scrum (2015/11/5)
这天晚上我们对爬虫进行了一些测试,发现仍然存在一些不小的BUG.现在我们的爬虫已经能完成基本的功能,焉域政同学也正在把他之前写的分类功能继续完善.在BUG的测试中,我们发现如果要求爬虫爬取特定的文件类 ...
- 设计与实现分离——面向接口编程(OO博客第三弹)
如果说继承是面向对象程序设计中承前启后的特质,那么接口就是海纳百川的体现了.它们都是对数据和行为的抽象,都是对性质和关系的概括.只不过前者是纵向角度,而后者是横向角度罢了.今天呢,我想从设计+语法角度 ...
- 奔跑吧DKY——团队Scrum冲刺阶段-Day 1-领航
各个成员在 Alpha 阶段认领的任务 修改 序号 修改 具体描述 1 游戏过程 取消原来的跳跃和俯身按钮,保留跳跃的功能,可以触屏滑动来躲避地面障碍物,也可以躲避另一种陷阱障碍物 2 闯关功能 取消 ...
- 假如 GFW 遇上 ML
我稍微试了一下梯子 我稍微试了一下梯子,在有梯子的情况下进行google搜索,然后wireshark 抓包.所有问题跃然纸上 当前我认为:> 只要你和一个非国内的服务器长时高频交换数据,基本上就 ...
- NABCD(网上投票系统)
网上投票系统 N(need) 投票这件事情,在所有事情上都可能用得到,在互联网的影响下,投票的范围变得越来越广,比如在商业的里,往往要做市场分析,那么在互联网这个大的前提下,用网上投票系统来获取用户的 ...
- mvc学习-编辑提交需要注意-mvc重点
示例代码: // GET: /Movies/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpSt ...