dfs序就是一棵树在dfs遍历时组成的节点序列.

它有这样一个特点:一棵子树的dfs序是一个区间.
下面是dfs序的基本代码:
void dfs(int x,int pre,int d){//L,R表示一个子树的范围
L[x]=++tot;
dep[x]=d;
for(int i=;i<e[x].size();i++){
int y=e[x][i];
if(y==pre)continue;
dfs(y,x,d+);
}
R[x]=tot;
}

给定一颗树, 和每个节点的权值.下面有7个经典的关于dfs序的问题:

1. 对某个节点X权值加上一个数W, 查询某个子树X里所有点权的和.

由于X的子树在DFS序中是连续的一段, 只需要维护一个dfs序列,用树状数组实现:单点修改和区间查询.

2. 对节点X到Y的最短路上所有点权都加一个数W, 查询某个点的权值.
这个操作等价于a. 对X到根节点路径上所有点权加W
b. 对Y到根节点路径上所有点权加W
c. 对LCA(x, y)到根节点路径上所有点权值减W
d. 对LCA(x,y)的父节点 fa(LCA(x, y))到根节点路径上所有权值减W

于是要进行四次这样从一个点到根节点的区间修改.将问题进一步简化, 进行一个点X到根节点的区间修改, 查询其他一点Y时,只有X在Y的子树内, X对Y的值才有贡献且贡献值为W.当单点更新X时,X实现了对X到根的路径上所有点贡献了W.于是只需要更新四个点(单点更新) ,查询一个点的子树内所有点权的和(区间求和)即可.

3. 对节点X到Y的最短路上所有点权都加一个数W, 查询某个点子树的权值之和.
同问题2中的修改方法, 转化为修改某点到根节点的权值加/减W
当修改某个节点A, 查询另一节点B时
只有A在B的子树内, Y的值会增加
W * (dep[A] - dep[B] + 1) => W * (dep [A] + 1) - W * dep[B]
那么我们处理两个数组就可以实现:
处理出数组Sum1,每次更新W*(dep[A]+1),和数组Sum2,每次更新W.
每次查询结果为Sum1(R[B]) – Sum1(L[B]-1) - (Sum2(R[B]) – Sum2(L[B]-1)) * dep [B].

4. 对某个点X权值加上一个数W, 查询X到Y路径上所有点权之和.
求X到Y路径上所有的点权之和, 和前面X到Y路径上所有点权加一个数相似
这个问题转化为
X到根节点的和 + Y到根节点的和 - LCA(x, y)到根节点的和 - fa(LCA(x,y)) 到根节点的和
更新某个点x的权值时,只会对它的子树产生影响,对x的子树的每个点到根的距离都加了W.
那么我们用”刷漆”(差分前缀和),更新一个子树的权值.给L[x]加上W,给R[x]+1减去W,那么sum(1~L[k])就是k到根的路径点权和.

5. 对节点X的子树所有节点加上一个值W, 查询X到Y的路径上所有点的权值和
同问题4把路径上求和转化为四个点到根节点的和
X到根节点的和 + Y到根节点的和 - LCA(x, y)到根节点的和 - parent(LCA(x,y)) 到根节点的
再用刷漆只更新子树.
修改一点A, 查询某点B到根节点时, 只有B在A的子树内, A对B才有贡献.
贡献为W * (dep[B] - dep[A] + 1) => W * (1 - dep[A]) + W * dep[B]
和第三题一样, 用两个sum1,sum2维护 W *(dep[A] + 1),和W.
最后答案就是sum2*dep[B]-sum1.

6. 对子树X里所有节点加上一个值W, 查询某个点的值.
对DFS序来说, 子树内所有节点加W, 就是一段区间加W.
所以这个问题就是 区间修改, 单点查询.树状数组+刷漆.

7.对子树X里所有节点加上一个值W, 查询某个子树的权值和.
子树所有节点加W, 就是某段区间加W, 查询某个子树的权值和, 就是查询某段区间的和
区间修改区间求和,用线段树可以很好解决.

 
 

DFS序详解的更多相关文章

  1. JS-排序详解:冒泡排序、选择排序和快速排序

    JS-排序详解-冒泡排序 说明 时间复杂度指的是一个算法执行所耗费的时间 空间复杂度指运行完一个程序所需内存的大小 稳定指,如果a=b,a在b的前面,排序后a仍然在b的前面 不稳定指,如果a=b,a在 ...

  2. JS-排序详解-冒泡排序

    说明 时间复杂度指的是一个算法执行所耗费的时间 空间复杂度指运行完一个程序所需内存的大小 稳定指,如果a=b,a在b的前面,排序后a仍然在b的前面 不稳定指,如果a=b,a在b的前面,排序后可能会交换 ...

  3. JS-排序详解-选择排序

    说明 时间复杂度指的是一个算法执行所耗费的时间 空间复杂度指运行完一个程序所需内存的大小 稳定指,如果a=b,a在b的前面,排序后a仍然在b的前面 不稳定指,如果a=b,a在b的前面,排序后可能会交换 ...

  4. JS-排序详解-快速排序

    说明 时间复杂度指的是一个算法执行所耗费的时间 空间复杂度指运行完一个程序所需内存的大小 稳定指,如果a=b,a在b的前面,排序后a仍然在b的前面 不稳定指,如果a=b,a在b的前面,排序后可能会交换 ...

  5. Hadoop(四)HDFS集群详解

    前言 前面几篇简单介绍了什么是大数据和Hadoop,也说了怎么搭建最简单的伪分布式和全分布式的hadoop集群.接下来这篇我详细的分享一下HDFS. HDFS前言: 设计思想:(分而治之)将大文件.大 ...

  6. adoop(四)HDFS集群详解

    阅读目录(Content) 一.HDFS概述 1.1.HDFS概述 1.2.HDFS的概念和特性 1.3.HDFS的局限性 1.4.HDFS保证可靠性的措施 二.HDFS基本概念 2.1.HDFS主从 ...

  7. dfs序+RMQ求LCA详解

    首先安利自己倍增求LCA的博客,前置(算不上)知识在此. LCA有3种求法:倍增求lca(上面qwq),树链剖分求lca(什么时候会了树链剖分再说.),还有,标题. 是的你也来和我一起学习这个了qwq ...

  8. 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)

    参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...

  9. 【转】logback 常用配置详解(序)logback 简介

    原创文章,转载请指明出处:http://aub.iteye.com/blog/1101222, 尊重他人即尊重自己 详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透 ...

随机推荐

  1. C++多线程2

    #include "stdafx.h" #include <windows.h> int g_count; ; DWORD __stdcall Func(LPVOID ...

  2. hive问题整理(待续)

    本人对hadoop生态系统的环境搭建.配置相关再熟悉不过了,周末刚测试过oozie相关的 今早使用hive,报错: Exception in thread "main" java. ...

  3. Total Commander 8.52 Beta 1

    Total Commander 8.52 Beta 1http://www.ghisler.com/852_b1.php 10.08.15 Release Total Commander 8.52 b ...

  4. 802.11MAC基础

    做无线网络测试已经大半年了,在这过程中发现<802.11权威指南>真是以本好书,在这里分享一下学习到的知识,也帮助我记忆. 1.MAC: mac(媒介访问控制层),它位于物理层之上,控制着 ...

  5. java web开发小细节

    <!--1. 在form表单中的action里用绝对路径而不是相对路径--> <form action="${basePath}loginForm" name=& ...

  6. html基础01

    一.HTML 基础 1.HTML基础标签:<head> <bady> <tittle>XXX<tittle>:为标签 2.HTML标题 <h1&g ...

  7. Go语言并发编程示例 分享(含有源代码)

    GO语言并发示例分享: ppt http://files.cnblogs.com/files/yuhan-TB/GO%E8%AF%AD%E8%A8%80.pptx 代码, 实际就是<<Go ...

  8. 【笔记】ListView的使用

    1.0 ListView三要素 1.0.1  创建基本步骤 1.在布局文件中创建一个ListView组件,并在Activity中声明这个组件. 2.在Activity中,创建一个合适的Adapter. ...

  9. docker基本操作

    centos 7 安装docker 目前,CentOS 仅发行版本中的内核支持 Docker. Docker 运行在 CentOS 7 上,要求系统为64位.系统内核版本为 3.10 以上. Dock ...

  10. ie9 placeholder兼容

    .phcolor{ color:#999;}//css样式 function isPlaceholer(){ var input = document.createElement("inpu ...