参考博文:http://blog.csdn.net/qwe2434127/article/details/49819975

http://blog.csdn.net/qq_24489717/article/details/50569644

dfs序比较重要的性质:一棵子树的所有节点在dfs序里是连续一段,主要就是利用这个性质来解题.

作为预处理,首先将将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致。

然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]。

最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出来即可,由于对于 每个深度的所有节点,相对顺序和前序遍历的顺序以致,那么他们的dfs进入时间戳也是递增的,于是可以通过二分搜索求解。

Poj 3321:

题型一:对某个点X权值加上一个数W,查询某个子树X里所有点权值和。

解:列出dfs序,实现修改一个数,查询一段序列的和,显然这个序列可以用树状数组维护。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long LL;
const int N = ;
struct Edge{
int v,next;
}edge[N];
int head[N],tot,c[N];
int in[N],out[N];
bool have[N];
int cnt;
void init(){
tot = ;
cnt = ;
memset(head,-,sizeof(head));
memset(c,,sizeof(c));
}
void addEdge(int u,int v,int &k){
edge[k].v = v,edge[k].next = head[u],head[u] = k++;
}
void dfs(int u){
in[u] = ++cnt;
for(int k=head[u];k!=-;k=edge[k].next){
dfs(edge[k].v);
}
out[u] = cnt;
}
int lowbit(int x){
return x&(-x);
}
int getsum(int id){
int sum = ;
for(int i=id;i>=;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void update(int id,int x){
for(int i=id;i<=cnt;i+=lowbit(i)){
c[i]+=x;
}
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF){
init();
for(int i=;i<n-;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v,tot);
}
dfs();
/*for(int i=1;i<=n;i++){
printf("%d %d\n",in[i],out[i]);
}*/
for(int i=;i<=n;i++){
have[i] = ;
update(in[i],);
}
int q;
scanf("%d",&q);
while(q--){
char s[];
int x;
scanf("%s%d",s,&x);
if(s[]=='Q'){
printf("%d\n",getsum(out[x])-getsum(in[x]-));
}else{
if(have[x]) update(in[x],-);
else update(in[x],);
have[x] = !have[x];
}
}
}
return ;
}

hdu 3886 :

统计某一个结点下面比编号比其小的结点数目.

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long LL;
const int N = ;
struct Edge{
int v,next;
}edge[N];
int head[N],tot,c[N];
int in[N],out[N];
bool have[N];
int cnt;
void init(){
tot = ;
cnt = ;
memset(head,-,sizeof(head));
memset(c,,sizeof(c));
}
void addEdge(int u,int v,int &k){
edge[k].v = v,edge[k].next = head[u],head[u] = k++;
}
void dfs(int u,int fa){
in[u] = ++cnt;
for(int k=head[u];k!=-;k=edge[k].next){
if(edge[k].v == fa) continue;
dfs(edge[k].v,u);
}
out[u] = cnt;
}
int lowbit(int x){
return x&(-x);
}
int getsum(int id){
int sum = ;
for(int i=id;i>=;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void update(int id,int x){
for(int i=id;i<=cnt;i+=lowbit(i)){
c[i]+=x;
}
}
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF,n+q){
init();
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v,tot);
addEdge(v,u,tot);
}
dfs(q,-);
bool flag = true;
for(int i=;i<=n;i++){
if(!flag) printf(" ");
printf("%d",getsum(out[i])-getsum(in[i]-));
flag = false;
update(in[i],);
}
printf("\n");
}
return ;
}

hdu 5692:利用DFS序将树形结构转换成为线段树.便于维护和查找.

http://www.cnblogs.com/liyinggang/p/5925196.html

hdu 5468:DFS序+容斥原理 ,求解每个结点下面与其互质的结点的个数。

http://www.cnblogs.com/liyinggang/p/5926105.html

bzoj 2819:DFS序+博弈+树状数组+lca,维护树上的一条路上的异或值.

http://www.cnblogs.com/liyinggang/p/5927232.html

update中...

dfs序题目练习的更多相关文章

  1. DFS序的题目列表

    所谓dfs序就是将之前的顺序进行修改,获得一个新的序列,然后再新的序列下进行一系列其他的操作 一般题目给你的都会是一棵树,然后点之间都是无关的,我们首要的任务就是先把这些序列重新排.然后再根据dfs的 ...

  2. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

  3. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  4. DFS序+线段树 hihoCoder 1381 Little Y's Tree(树的连通块的直径和)

    题目链接 #1381 : Little Y's Tree 时间限制:24000ms 单点时限:4000ms 内存限制:512MB 描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每 ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)

    题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...

  7. dfs序

    dfs序比较重要的性质:一棵子树的所有节点在dfs序里是连续一段,主要就是利用这个性质来解题 题型一:对某个点X权值加上一个数W,查询某个子树X里所有点权值和. 解:列出dfs序,实现修改一个数,查询 ...

  8. [BZOJ 2819]NIM(dfs序维护树上xor值)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2819 分析: 树上的nim游戏,关键就是要判断树上的一条链的异或值是否为0 这个题目有 ...

  9. 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 130[Submit][Status][Discuss] D ...

随机推荐

  1. hdu5279 YJC plays Minecraft 【分治NTT】

    题目链接 hdu5279 题解 给出若干个完全图,然后完全图之间首尾相连并成环,要求删边使得两点之间路径数不超过\(1\),求方案数 容易想到各个完全图是独立的,每个完全图要删成一个森林,其实就是询问 ...

  2. hadoop(二)hadoop集群的搭建

    一.集群环境准备工作 1.修改主机名 在root 账户下 vi /etc/sysconfig/network   或者 sudo vi /etc/sysconfig/network 2.设置系统默认启 ...

  3. 在 Xamarin.Forms 实现密码输入EntryCell

    在 Xamarin.Forms 中,我们通常使用 TableView 来构建输入表单.Xamarin 为我们提供了 EntryCell 用于输入文本,但是其并不支持密码输入,即密码掩码.这里要对 En ...

  4. 【树链剖分换根】P3979 遥远的国度

    Description zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcw ...

  5. db2 数据库操作JDBC .addBatch() 方法执行时,报错排查结果

    今天调试db2数据的存储时,jdbc使用addBatch方法时,抛出异常,异常信息如下: [jcc][1091][10404][3.62.56] 数据转换无效:参数实例  对于所请求的转换无效. ER ...

  6. joomla! 3.X 开发系列教程

    http://www.mengyunzhi.com/members-resource/joomla/87-joomla-menu-study.html 学习地址 http://blog.csdn.ne ...

  7. jquery、css3动态显示百分比圆

    动态显示百分圆 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <m ...

  8. PID控制算法的C语言实现一 PID算法原理

    本系列是转载............. 全部的程序有一个共同点:就是我没认真去调pid的参数 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设 ...

  9. SSM与SSH的对比

    struts与springMVC的对比: 1.核心控制器(前端控制器.预处理控制器):负责接收页面请求和返回数据给页面. 对于使用过mvc框架的人来说这个词应该不会陌生,核心控制器的主要用途是处理所有 ...

  10. SQL Server清理Log文件

    ---SQL 2008 在SQL2008中清除日志就必须在简单模式下进行,等清除动作完毕再调回到完全模式. USE [master] go ALTER DATABASE PS SET RECOVERY ...