前言
Euler Tour of A Tree
ETT即Euler-Tour-Tree,也就是采用欧拉序来访问一棵有n个node的树,例如上图所示的这棵树,欧拉序为:9 2 1 7 1 8 1 2 4 2 6 2 9 3 9 5 9;即从根节点开始,dfs(深度优先遍历,前序遍历)依次输出访问边对应的节点,Euler Tour的长度是2n-1,因为每次遍历一条边时输出一个节点,遍历了n-1条边两次,每个方向一次。这样的好处是,可以通过欧拉序列知道所有子树的信息,比如以1为根节点的子树就包括 (1 7 1 8 1),1、7和8这3个节点;还可以快速得到根节点:(7 1 8)序列中层数最浅的是1,说明1为该子树的根节点。
RMQ(Range Minimum Query)
RMQ范围最小值查找就是给定一个数组,找到该范围内最小元素的索引。LCA问题可以规约为RMQ问题。
LCA
Naive Algorithm
(1)用数组来按顺序存储Euler Tour访问的节点;
(2)用数组存储
对应节点的高度(即节点到根节点的距离);
(3)用数组存储每个节点
在Euler Tour中第一次出现的索引,即
;
(4)两个节点第一次出现之间访问的节点为
或者
,在这个子序列中最浅的节点即高度最小的就是
的LCA,即
。
该方法预处理阶段的时间复杂度为,差不多是暴力解法。
Faster RMQ Algorithm
思想——用一个二维表来提前将RMQ的最小值计算并进行存储。
(1)对于每一个和
,找到区块
的最小的元素并存储在
中,即
,表
的大小为
。
(2)使用dynamic programming(DP思想)填满只需要
的时间复杂度:对于
大小的block,只需计算其两个连续子block的最小值,即
。
(3)即使用Sparse Table(ST)来计算RMQ,并需要类似找the most significant bit of a word的操作。
(4)查询:我们需要两个已知的固定区间,能够覆盖(可以重合一部分)整个查询区间。为了方便查找,我们规定这两个已知区间覆盖的区间长度均为2^k,并且两个区间分别有一端为L和R。那么随着这个k不断增大,一定存在一个临界点k,刚好覆盖(或最少重合)这个区间。当k满足题意时,两个区间分别为[L,L+2k−1][L,L+2k−1]和[R−(2k−1),R][R−(2k−1),R],此时只需要满足R−(2k−1)≤L+2k−1R−(2k−1)≤L+2k−1即可,化简之后推出公式:R−L+2≤2k+1,k≥log2(R−L+2)−1。
Fast Algorithm for ![\pm 1 RMQ](https://private.codecogs.com/gif.latex?%5Cpm%201%20RMQ)
思想——基于限制,使用查表方法提前计算小数组的答案,来消除log。
指任何邻接的两个节点间的高度差为1或-1.
(1)将数组A按每个block大小为进行划分,得到
;
(2)定义一个等大的数组B,表示第
个block里最小元素出现的位置;
(3)查询:当查询的起点和
不在一个block里时,1)找到从
到
所在的block里最后一个元素的最小值;2)查找
和
之间所有block的最小值;3)查找从
所在block起始位置到
的最小值。
(4)in-block查询优化:对于(3)中的2)的值可以使用ST表实现常数时间复杂度的查询,因此现在主要是优化1)和3)的in-block查询。使用Normalized Block,即依次处理每个block中元素将其将去最初的每个元素,那么对于长度为的block,共由
种不同的Normalized Blocks。其余相同的Normalzed Block可以使用相同的预处理,这大大提高了预处理时间。
(5)创建个table,每个table对应一种Normalized Block。每个Block中保存
种查询结果。
[References]:
M. A. Bender and M. Farach-Colton. The lca problem revisited. In Proc. of LASTI’00, pages 88–94, 2000.