POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

题意分析

卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果。卡卡很喜欢苹果。树上有N个节点,卡卡给他们编号1到N,根的编号永远是1.每个节点上最多结一个苹果。卡卡想要了解某一个子树上一共结了多少苹果。

现在的问题是不断会有新的苹果长出来,卡卡也随时可能摘掉一个苹果吃掉。你能帮助卡卡吗?

前缀技能

边表存储树

DFS时间戳

线段树

首先利用边表将树存储下来,然后DFS打上时间戳。打上时间戳之后,我们就知道书上节点对应维护线段树的哪一段区间了。换句话说,每当题目给出一个点,要求更新的时候,我们根据时间戳,确定其点在线段树上的位置。当题目给出一个区间,要求我们查询的时候,再根据时间戳,确定线段树区间左右端点。如此一来,就可以将树上信息,转换到线段树上来维护。

注意

  1. 值得注意的是,我的边表存的是两条边,所以边表的容量要开二倍。
  2. 其次就是,无论在更新的时候,还是在查询的时候,要根据时间戳,转化到线段树的对应点或者区间上。因为这个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序 线段树 单点更新 区间求和)的更多相关文章

  1. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  2. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  3. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  4. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu1166(线段树单点更新&区间求和模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:中文题诶- 思路:线段树单点更新,区间求和模板 代码: #include <iost ...

  6. POJ 3321 Apple Tree DFS序 + 树状数组

    多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...

  7. POJ3321 - Apple Tree DFS序 + 线段树或树状数组

    Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...

  8. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  9. POJ 3321 Apple Tree DFS序+fenwick

    题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思 ...

随机推荐

  1. Datawhale MySQL 训练营 Task2 查询语句

    目录 MySQL 管理 MySQL 用户管理 参考 数据库管理 SQ查询语句 1. 导入示例数据库,教程 MySQL导入示例数据库 2. 查询语句 SELECT 3. 筛选语句 WHERE ,过滤 4 ...

  2. 帝国cms后台集成ueditor编辑器

    我更换成百度编辑器的原因有以下几点:1.使用百度编辑器的图片粘贴上传功能,这个功能实在是太有必要了,有开发的过程中或上传的过程中,通常用qq直接截图,直接放到文章上面,避免了再放到本地保存的情况,真是 ...

  3. HIVE函数的UDF、UDAF、UDTF

    一.词义解析 UDF(User-Defined-Function) 一进一出 UDAF(User- Defined Aggregation Funcation) 多进一出 (聚合函数,MR) UDTF ...

  4. Linux文件句柄数调整

    首先介绍下Linux系统中"一切都是文件". 1. Linux系统文件句柄数概念 文件句柄(Windows) 文件描述符(Unix/Linux):file discriptor,f ...

  5. [linux] 利用PROMPT_COMMAND实现命令审计

    网上查了实现命令审计大概有以下几种: 查不到了,改天再补充 以下环境基于CentOS 6 1.修改history时间格式 echo 'HISTTIMEFORMAT="%F %T " ...

  6. 大华摄像头WEB页面集成

    对于海康.大华的摄像头web页面内的集成方式,根据浏览器类型,通常是采用以下形式: IE内核:调用ocx控件 例如: <object width="100%" height= ...

  7. Scrum Meeting 11 -2014.11.17

    今天和其他两个小组讨论了关于整合问题,在数据库连接等具体方面上还需要继续商讨. 我们小组内部讨论了,这周还是需要在处理整合的同时做项目整体的测试与改进的. Member Today’s task Ne ...

  8. bing词典vs有道词典对比测试报告——功能篇之细节与用户体验

    之所以将细节与用户体验放在一起讨论,是因为两者是那么的密不可分.所谓“细节决定成败”,在细节上让用户感受方便.舒适.不费心而且温馨,多一些人文理念,多一些情怀,做出来的产品自然比其他呆板的产品更受欢迎 ...

  9. teamwork 2

    1.访问上学期项目团队,学习他们的得失. 上学期学长们有一个项目是学霸系统,在看过了学长们的相关博客后,我们可以感受到学长们确实花费了不少心思,也看到了许多值得我们学习的地方. 首先,学长们在项目开始 ...

  10. git 提交本地文件,删除文件夹,修改文件等

    1. 下载git工具包 链接: https://git-scm.com/download/win 2. 右键打开git bash 登陆到自己的github账户 $ git config --globa ...