poj3321(dfs序+树状数组)
题目链接: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序+树状数组)的更多相关文章
- poj3321 dfs序+树状数组单点更新 好题!
当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题 树的dfs序映射在树状数组上进行单点修改,区间查询. /* 树状数组: lowbit[i] = i&-i C[i] = a[i-l ...
- HDU 3887:Counting Offspring(DFS序+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- 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 ...
- BZOJ 2434: [Noi2011]阿狸的打字机( AC自动机 + DFS序 + 树状数组 )
一个串a在b中出现, 那么a是b的某些前缀的后缀, 所以搞出AC自动机, 按fail反向建树, 然后查询(x, y)就是y的子树中有多少是x的前缀. 离线, 对AC自动机DFS一遍, 用dfs序+树状 ...
- 【bzoj3881】[Coci2015]Divljak AC自动机+树链的并+DFS序+树状数组
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- [BZOJ1103][POI2007]大都市meg dfs序+树状数组
Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n ...
- 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)
传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
- 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)
题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...
随机推荐
- centos6 安装teamviewer
wget http://www.teamviewer.com/download/teamviewer_linux.rpm yum -y install temviewerX.rpm 机器最好联网,能够 ...
- js闭包(二)
一.何谓“闭包”? 所谓“闭包(Closure)”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 描述的如此学术的官方解释,相信很少人能够 ...
- springboot启动过程(1)-初始化
1 springboot启动时,只需要调用一个类前面加了@SpringBootApplication的main函数,执行SpringApplication.run(DemoApplication. ...
- Ros学习——录制与回放
mkdir ~/bagfiles cd ~/bagfiles rosbag record -a 录制完成后,查看文件: rosbag info <your bagfile> 回放:在终端中 ...
- Mind Map - FreeMind
FreeMind[1]是一款基于java的免费的脑图(mind mapping)制作与管理软件.FreeMind开发项目组正致力于使其成为一款高效率的工具.FreeMind具有一键“展开/折叠”功能以 ...
- 51NOD1835 完全图
传送门 分析 令f(i,j)表示i点完全图有j个联通块的方案数. 讨论有i-1个点已经固定了,我们拉出一个代表元素然后讨论它的集合大小然后组合数算一下就可以了. $$ dp(i,j) = \sum_{ ...
- HTML5应用程序缓存Application Cache.RP
什么是Application Cache HTML5引入了应用程序缓存技术,意味着web应用可进行缓存,并在没有网络的情况下使用,通过创建cache manifest文件,可以轻松的创建离线应用. A ...
- HUST高级软件工程--测试管理工具实践--Day2
测试管理工具实践--Day2 今天完成任务情况: 小靳 今天主要探索如何安装jira.在官网下载了最新版Windows64位jira,然后按照网上教程走,设置好端口号.在安装之前自以为这款软件在安装的 ...
- emr问题处理
--通过his病历号查询emr中对应的患者ID --通过患者ID找出患者所有的病历集合ID --通过病历集合查找患者所有的病历 --通过病历dataID查找对应的病历数据,病历存在大字段中 '; -- ...
- Cyber-Ark spring mvc @autowired
我们帮助中国平安改进他们重要系统的特权帐号密码管理,提供给他们一个“统一的,集中的,安全的”特权帐号密码管理解决方案.完全满足平安信息安全部对“特权帐号生命周期管理”的理解和需求,而且关键组件的高可用 ...