数据结构 《18》----RMQ 与 LCA 的等价性 (一)

前言

    RMQ: 数组 a0, a1, a2,..., an-1, 中求任意区间 a[i+1], a[i+2], ..., a[i+k] 的最小值

    LCA: 求二叉树中两个节点的最低公共祖先

本文将证明这两个问题可以相互归约为另一个问题。

证明

先通过一个简单的例子来说明问题。见下图:

求 [7 2 8 6] 的最小值 2,等价于求二叉树中节点 7 和 节点6的 LCA,也就是 节点2。

有意思吧。。。

一、 RMQ -> LCA

给定一个数组,如何求出其对于的二叉树呢??

方法1: 这棵二叉树其实具有类似最小堆的性质(虽然不是完全二叉树),

可以采用递归建树,先找到最小值作为 root 节点,然后对最小值左半边和右半边递归建左子树和右子树即可。

复杂度: 最好 O(NlgN),最坏 O(N^2), 分析类似与快排。。

方法2:因此扫描数组的每一个元素,将元素按如下规则插入树中;

从根节点出发,一直往右孩子移动,直到当前插入元素值位于一个 父亲节点和右孩子节点之间。

将插入节点作为 父亲节点的右孩子,之前的右子树作为插入节点的左子树。

二、LCA -> RMQ

如何将一个 LCA 归约到一个数组求区间最小值呢?? 这个问题有一个 trick.

加入我们的二叉树如下图,注意,它并不满足最小堆的性质!!!

1. 做一个变换,将节点的值改成节点的深度,这样,新的二叉树就满足了最小堆的性质;

这两颗树的节点是一一对应的,

求 LCA(node3, node8) 对应于 在新树中求 LCA(node3, node1)

2. 新树中求 LCA(node3, node1) 对应于在新树的中序遍历序列 2 1 3 2 0 1 中求 【3 2 0 1】的最小值;

数据结构 《18》----RMQ 与 LCA 的等价性 (一),码迷,mamicode.com

时间: 2024-10-07 05:53:37

数据结构 《18》----RMQ 与 LCA 的等价性 (一)的相关文章

RMQ与LCA

一.什么是LCA? LCA:Least Common Ancestors(最近公共祖先),对于一棵有根树T的任意两个节点u,v,求出LCA(T, u, v),即离跟最远的节点x,使得x同时是u和v的祖先. 二.算法分类 求LCA的算法很多,按照是否在线可以分为在线算法和离线算法.      在线算法:用比较长的时间做预处理,但是等信息充足以后每次回答询问只需要用比较少的时间.      离线算法:先把所有的询问读入,然后一起把所有询问回答完成,不是本文所讲,Click here 三.在线算法 (

自动机的等价性

什么是自动机的等价性:前面我们讲过如果两个文法生成的语言相同,那么我们认为这两个文法是等价的.这里道理是一样的,如果两个自动机识别的语言相同,那么我们也认为它们是等价的.为了讨论自动机的等价性,需要先对自动机中的映射进行扩展. 1,对自动机的映射进行扩展 原来的映射 t:Q × ∑ → Q            扩展之后的映射 t:Q × ∑* → Q DFA 扩展之后的映射定义为: t(q,ε) = q t(q,aα) = t(t(q,a),α)  其中,q ∈ Q,a ∈ ∑,α ∈ ∑*.

【转】Eric's并发用户数估算与Little定律的等价性

转自:http://www.cnblogs.com/hundredsofyears/p/3360305.html 在国内性能测试的领域有一篇几乎被奉为大牛之作的经典文章,一个名叫Eric Man Wong 于2004年发表了名为<Method for Estimating the Number of Concurrent Users>,里面介绍了一种对系统并发用户数估算的公式,并较为详细的阐述了过程以及证明方法.这个公式使用非常简单,很多性能测试工程师都在自己的项目中使用或者打算尝试使用,以至

【RMQ】洛谷P3379 RMQ求LCA

题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每行包含两个正整数x.y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树). 接下来M行每行包含两个正整数a.b,表示询问a结点和b结点的最近公共祖先. 输出格式: 输出包含M行,每行包含一个正整数,依次为每一个询问的结果. 输入输出样例 输入样例#1: 复制 5 5 4 3 1 2 4

软件构造 第三章第五节 ADT和OOP中的等价性

第三章第五节 ADT和OOP中的等价性 1.==与equals ==是引用等价性 :而equals()是对象等价性. == 比较的是索引.更准确的说,它测试的是指向相等(referential equality).如果两个索引指向同一块存储区域,那它们就是==的.对于我们之前提到过的快照图来说,==就意味着它们的箭头指向同一个对象. equals()操作比较的是对象的内容,换句话说,它测试的是对象值相等(object equality).在每一个ADT中,equals操作必须合理定义 2.等价性

抽象数据类型(ADT)和面向对象编程(OOP)3.5 ADT和OOP中的等价性

instancsof动态类型检查.除了在判断是否与应生成的类型一样外都不使用,getClass()同样 ==引用等价性 equals()对象等价性  基本数据类型使用 在自定义ADT时需要重写Object的equals()   对象类型使用 a.equals(null) returns false equals()的自反性:自己等自己   传递性:a等b,b等c,则a等c   对称性:a等b,则b等a 重写equals()必须也要重写hashCode(),相等的对象必须具有相同的散列码,如果没有

dfs序+RMQ求LCA详解

首先安利自己倍增求LCA的博客,前置(算不上)知识在此. LCA有3种求法:倍增求lca(上面qwq),树链剖分求lca(什么时候会了树链剖分再说.),还有,标题. 是的你也来和我一起学习这个了qwq. 开始吧. 众所周知,每当你dfs时,你都能产生一棵dfs树,可以根据你的dfs序来构建. such as(丑陋的画风): 一个dfs的顺序. 以这个为例: 那么我们写出他的遍历顺序: 假如我们要求3,8(wtf?)的LCA, 那么我们首先写出他的bfs序: 123432565217871. 然后

『数据结构』RMQ问题

RMQ(Range Minimum/Maximum Query),即区间最值问题. 对于长度为 n 的数列 A ,回答若干查询 RMQ(A,i,j)(i,j<=n) ,返回数列 A 中下标在 i,j 里的最大(小)值. 相关算法 朴素(搜索),时间复杂度:\(O(n)-O(q \times n)\) ,在线: 线段树,时间复杂度:$O(n)-O(q\times logn) $,在线: ST(动态规划),时间复杂度:\(O(n\times logn)-O(q)\),在线: RMQ标准算法,先规约为

C++和C的结构等价性的不同

C++中,结构按名称等价,而C中,结构按布局相容性等价. 1 struct A 2 { 3 int x,y; 4 }; 5 6 struct B 7 { 8 int x,y; 9 }; 10 11 int main() 12 { 13 struct A a; 14 struct B b; 15 struct A *pa = &a; 16 struct B *pb = &b; 17 pa = pb; 18 return 0; 19 } 该代码在纯C编译环境中,能顺利通过,一般会给出警告信息告