其他分享
首页 > 其他分享> > 树的dfs序

树的dfs序

作者:互联网

二叉树

对于一颗二叉树,它有三种遍历方式:前序、中序、后序
这三种顺序其实都有使用的场景(主要是在分治算法中考虑是递归前,递归进行中,递归后)的区别。

多叉树

在多叉树里面,常用的dfs序其实也有三种:dfs序、扩展dfs序、欧拉序
dfs序类似二叉树的先序遍历
扩展dfs序类似二叉树的先序+中序
欧拉序类似二叉树的先序+后序

在树上问题中dfs序列往往是为了构建“树”与“序列”的桥梁。绝大部分的“子树”操作类问题,“树链”操作问题,其实本质来讲都是利用了dfs序列将树结构整理成数组。

树的dfs序

对于一颗多叉树,发现将其利用dfs序重标号后,每一颗子树的dfs序全都是连续的。
定义L[x]数组表示在dfs遍历的过程中x所覆盖子树的dfn最小值。
定义R[x]数组表示在dfs遍历的过程中x所覆盖子树的dfn最大值。
有了LR数组,子树的维护问题就转化成了数组区间的维护问题

注意

id(L),R,idx这三个数组,我们接下来在学习轻重树链剖分,长链剖分,dsu on tree的时候还会继续用到它们。
实际上,所有关于树的dfs序列的算法你都可以预处理出这几个数组。

扩展dfs序

扩展dfs序是一种“类中序”的处理。
一般来讲对于多叉树是用不到这种类中序的,因为多叉树的多个子树不像二叉树有左右的顺序关系,但是扩展dfs序被巧妙的使用在了一个黑科技LCA的模板中。
该模板支持
O(NlogN)时间预处理。
O(1)在线查询任意两点的LCA。
听上去好像没有卵用,但是要看使用场景。
该模板的使用场景为:
树的尺寸N和LCA的查询数目M不对等,并且在数量级上至少有
N<M*10的关系,并且题目需要强制在线。
这个时候就可以掏出这个非常牛逼的模板了。
其实也不是啥黑科技,就是一个普通的ST实现的RMQ。

实现

与之前做的dfs序一样,数组的含义没变,同样是id(L),R,idx这些。
不一样的是,我们要做一个“类中序”,即在每个子树遍历前做一个对于当前节点的额外遍历,额外遍历不是真正的初次遍历,不需要维护id(L)数组。
在遍历的过程中,维护一个pair类型的ST表,piar<deep,id>ST。

特殊

很有趣,因为利用扩展dfs序,LCA问题竟然转化成了RMQ问题。
(反过来是不是也可以转化呢)
确实可以,利用笛卡尔树,可以将任意的RMQ问题转化成LCA问题。
笛卡尔树模型可以将和区间RMQ有关的问题(例如和RMQ问题有关的动态规划方程,区间DP等)转化成树上问题,然后可以利用树形DP求解。
扩展dfs序:LCA问题->RMQ问题
笛卡尔树:RMQ问题->LCA问题
所以你证明了,静态查询中LCA问题和RMQ问题是本质等价的。

标签:RMQ,dfs,子树,遍历,数组,LCA
来源: https://www.cnblogs.com/hh--boke/p/16457923.html