题目链接:https://vjudge.net/problem/POJ-3321

题意:给一个普通树(不是二叉树),并且已经编号,每个结点为1或0,有两种操作,对单个结点修改和查询一个结点的子树的所有结点的值。

思路:操作为单点操作和区间查询,很适合用树状数组或线段树来解,但是这里的区间查询并不具备减法规则,一个结点的子数的所有结点编号也不连续。

   所以需要我们自己来重新给结点编号。这里利用dfs对树遍历一遍,使用一个时间戳(从1开始),在遍历一个结点开始和结束分别记录时间戳s[i],e[i],能够发现s[i]即为结点i的新编号,s[i]~e[i]即为结点i的管辖范围(就是以i为根的子数的所有结点编号所在区间)。文字描述很抽象,下面举个例子:

对于上面所示树,数字为题目给的编号。dfs的遍历顺序为

i:       1      2       5       6      3       7      4      8      9

(s[i],e[i])    (1,9) (2,4) (3,3) (4,4) (5,6) (6,6) (7,9) (8,8) (9,9)

遍历结点开始时的时间戳表示结点编号这个很自然,遍历完这个结点的子树之后的时间戳其实就是子树结点的最后一个编号,所以s[i]~e[i]表示其子树的编号区间,一个子树的编号也是连续的。

然后就可以利用树状数组来解决剩下的问题了,对单点进行修改,对一个结点的子树进行查询,结果就是query(e[i])-query(s[i]-1)。复杂度为O(nlogn)。

AC代码:

#include<cstdio>
using namespace std;
const int maxn=; struct node{
int v,next;
}edge[maxn<<]; int head[maxn],tr[maxn],s[maxn],e[maxn];
bool vis[maxn],a[maxn];
int n,m,cnt,tim; void add(int u,int v){
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
} void dfs(int p){
s[p]=++tim;
vis[p]=;
for(int i=head[p];i!=-;i=edge[i].next){
if(vis[edge[i].v]) continue;
dfs(edge[i].v);
}
e[p]=tim;
} int lowbit(int x){
return x&(-x);
} void update(int x,int num){
while(x<=n){
tr[x]+=num;
x+=lowbit(x);
}
} int query(int x){
int ans=;
while(x>){
ans+=tr[x];
x-=lowbit(x);
}
return ans;
} int main(){
scanf("%d",&n);
for(int i=;i<=n;++i){
head[i]=-;
a[i]=;
update(i,);
}
for(int i=;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs();
scanf("%d",&m);
char c;
int t;
while(m--){
scanf(" %c%d",&c,&t);
if(c=='C'){
if(a[t]){
a[t]=;
update(s[t],-);
}
else{
a[t]=;
update(s[t],);
}
}
else{
printf("%d\n",query(e[t])-query(s[t]-));
}
}
return ;
}

poj3321(dfs序+树状数组)的更多相关文章

  1. poj3321 dfs序+树状数组单点更新 好题!

    当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题 树的dfs序映射在树状数组上进行单点修改,区间查询. /* 树状数组: lowbit[i] = i&-i C[i] = a[i-l ...

  2. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  3. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  4. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  5. BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )

    一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...

  6. 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  7. [BZOJ1103][POI2007]大都市meg dfs序+树状数组

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...

  8. 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)

    传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...

  9. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  10. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

随机推荐

  1. 数据库连接池在Tomcat中的几种配置方法

    数据库连接是一种关键的有限的昂贵的资源,这在多用户网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标,数据库连接池正是针对这个问题提出的. ...

  2. 12-01Js对象##正则表达式##

    正则表达式:是一个字符一个字符的验证,通过量词验证字符串: 1.什么是RegExp?RegExp是正则表达式的缩写.RegExp 对象用于规定在文本中检索的内容. 2.定义RegExp:var +变量 ...

  3. Shell杀tomcat进程

    一.killandclean.sh #!/bin/bash pid=($(ps -ef | grep tomcat | egrep -v grep | awk '{print $2}')) lengt ...

  4. Tomcat服务器简介

  5. zabbix监控报错zabbix server is not running: the information displayed may not be current

    zabbix监控搭建完后打开web界面http://xxx/zabbix报错: zabbix server is not running: the information displayed may ...

  6. css知多少(4)——解读浏览器默认样式(转)

    css知多少(4)——解读浏览器默认样式   上一节<css知多少(3)——样式来源与层叠规则>介绍了样式的五种来源,咱们再通过一张图回顾一下. 对于上面的三层,咱们大概都比较熟悉了.下面 ...

  7. 深入理解asp.net中的 __doPostBack函数

    前段时间做一个.net网站的时候,用到了模拟前端按钮刷新updatePanel进行局部刷新的时候,遇见了这个问题,当时没顾上记下来,查看网上资料,记下来留着以后查看. 很早以前,当我刚接触asp.NE ...

  8. 创建Mat对象

    Mat 是一个非常优秀的图像类,它同时也是一个通用的矩阵类,可以用来创建和操作多维矩阵.有多种方法创建一个 Mat 对象. 1.构造函数方法 下面是一个使用构造函数创建对象的例子. 常用的构造函数 2 ...

  9. 安装postman工具模拟请求

    扩展工具->: 注意,在创建快捷方式后,第一次打开这个工具,会让你注册信息,忽略它.关闭,重新打开postman工具,然后如下所示:

  10. MySQL中MyISAM引擎与InnoDB引擎性能简单测试

    [硬件配置]CPU : AMD2500+ (1.8G)内存: 1G/现代硬盘: 80G/IDE[软件配置]OS : Windows XP SP2SE : PHP5.2.1DB : MySQL5.0.3 ...