范围最小查询(Range Minimize Query)

问题描述

给定任意数组 ,对于任意 请给出区间 的最小值

Solutions

硬算

直接从 i 到 j 遍历,找到最小的

时间复杂度: 空间复杂度:

打小抄

提前记录每个查询,到查询时再找

时间复杂度:,构建时间 空间复杂度:

这里可以使用动态规划加速:

image-20221202205056974

时间复杂度:,构建时间 空间复杂度:

打缩印-Block Decomposition

将元素数组分成 个桶,每个桶里面求出最小值。

查询时:如果横跨整个桶,就按记录的桶中最小值来,反之还是要计算的。

image-20221202205225957

  • 时间复杂度:时间查询整个桶,查询分桶的
  • 构建时间:
  • 空间复杂度:
  • 最佳的: ,这时时间复杂度:

Sparse Tables

对于每个索引i,计算从i开始的范围的RMQ,大小为1、2、4、8、16、…、,直到越界

观察下面整个情况,2-7之间的最小值可以通过两个更小的子问题求出来。

image-20221202210515432

那么只需要可以一个更小的备忘录来查询

image-20221202211643246

这个备忘录保存了从i开始长度为的子数组的最小值,而且这个备忘录也可以用动态规划求解出来。

时间复杂度:,构建

空间复杂度:

组合查询

采用分桶的思想,将整个数组的RMQ分解成几个子RMQ,父子RMQ问题会采用不同的策略(比如线性,sparse),甚至父子RMQ问题都可以采用组合查询。

image-20221202212352847

我们采用记号 分别表示父子查询的构建耗时和单次查询耗时。(p=precompute,q=query)

那么组合查询的查询复杂度为 ,总构建时间 ,通过组合可构造出更小复杂度的算法

一些组合例子

比如组合sparse与线性

image-20221202212550223

构建:,查询

全用sparse

image-20221202212659046

构建:,查询

笛卡尔树

笛卡尔树可以在 的复杂度上解决RMQ问题。

问题转换

组合查询的查询复杂度为 ,总构建时间 ,记作

那么如果要构建复杂度为 的算法, 的复杂度为多少?

于是问题转换为:

能否在 时间构建数据结构,满足在很多个子数组中查询最小值下标,且查询时间复杂度为 。(这里可以把单个数字看作长度为1的数组

为什么这个问题会比之前的问题更简单?举个例子:

两个数组
10	30	20	40
166	361	261	464

无论你如何选择i,j,返回下标都一样!!!

这意味者RMQ问题在这两个数组上是等价的,返回的坐标相同,这里我们记作RMQ结构相同。

那么子RMQ问题就可以转换成有限个更小的RMQ问题,比如下面这个图。

如何判断RMQ结构是否相同

假设数组 B1 B2 长度都为 b,只要他们满足

就称其等价,记作

只要 ,那么最小值下标就相同,而且可以递归的应用到子数组上!

笛卡尔树结构如下:

  • 树的根是数组的最小元素。
  • 它的左右子树是通过递归构建形成的
  • 笛卡尔树的子数组的左、右最小值。
image-20221203194719734

那么是不是只要笛卡尔树形状相同,就可以说明俩数组等价啦

构建

构建复杂度如下:

image-20221203201630345

计算最小值,数组长为 的笛卡尔树一共 种,当 时复杂度不超过 ,总体复杂度

查询

image-20221203195620656

例题