RMQ (Range Minimum/Maximum Query)问题,即区间最值查询问题,是求解序列中的某一段的最值的问题。如果只需要询问一次,那遍历枚举(复杂度O(n))就是最方便且高效的方法,但如果询问次数很多(m次),O(nm)的复杂度可能就不够看了。比较容易想到的优化方法是运用预处理的思想,可以在O(n^2)的时间内预处理出所有区间的最大值,随后每一次查询都只需要O(1)的时间。这种方法在n较小但m非常大的情况下很实用,但如果n也很大的话,无论是空间还是时间都接受不了这个复杂度。

这种情况下,我们可以借助稀疏表(sparse table)和动态规划的思想,避免笨重的逐个预处理的方法:

设dp[i][j]代表从第i个元素开始,长度为2^j的区间中的最值。那么dp[i][0]就等于原序列中的第i个元素,dp[i][j]则可以由两段长度为2^(j-1)的区间合并而成。这样,就可以在o(nlogn)的时间内完成预处理。在查询时,任一区间都可以被已经预处理出来的两个区间恰好覆盖,找出这两个区间即可完成查询。预处理的时间和空间复杂度都为O(nlogn),查询为O(1)。

下面以最大值为例,附上实现代码和需要注意的细节。

1、预处理

int n;
int a[maxn], dp[maxn][maxj];//a为原序列,元素编号为1至n
void init()//预处理
{
for(int i = ;i <= n;i++)//初始化
{
for(int j = ;j < maxj;j++)
{
dp[i][j] = -INF;//这里可根据需要赋成其他值或是省略,此处为无穷小
}
dp[i][] = a[i];//dp的初始值
}
//因为状态转移是把两段较短的区间合并,所以要先处理出短的区间,j应在循环的外层
for(int j = ;( << j) <= n;j++)//1 << j 运用了位运算,代表2^j
{
for(int i = ;( << j) + i - <= n;i++)//dp[i][j]覆盖的区间为[i, (1 << j) + i - 1]
{
dp[i][j] = max(dp[i][j - ], dp[i + ( << (j - ))][j - ]);//状态转移方程,书写这里时要注意位运算符的优先级
}
}
}

2、查询

为了保证查询的准确性,待查区间一定要被预处理出来的区间恰好覆盖。实现这一点,只需要两段长度小于待查区间的且长度为2的幂的区间即可。例如区间[1, 5]可以用[1, 4]和[2, 5]来覆盖。

如果待查区间长度为len的话,我们只需要查询长度为2^的两段区间就可以了(注意log得到的结果这里向下取整了)。

int ask(int l, int r)//查询[l, r]中的最大值
{
int len = r - l + , k = ;//len为待查区间长度
while( << (k + ) <= len)
k++;
//k代表原区间可以由两段长为2^k的区间覆盖
return max(dp[l][k], dp[r - ( << k) + ][k]);
}

动态规划——稀疏表求解RMQ问题的更多相关文章

  1. 算法学习 - ST表 - 稀疏表 - 解决RMQ问题

    2017-08-26 21:44:45 writer:pprp RMQ问题就是区间最大最小值查询问题: 这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j ...

  2. 基于稀疏表(Sparse Table)的RMQ(区间最值问题)

    在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...

  3. RMQ (Range Minimal Query) 问题 ,稀疏表 ST

    RMQ ( 范围最小值查询 ) 问题是一种动态查询问题,它不需要修改元素,但要及时回答出数组 A 在区间 [l, r] 中最小的元素值. RMQ(Range Minimum/Maximum Query ...

  4. [TJOI2017] DNA - 后缀数组,稀疏表

    [TJOI2017] DNA Description 求模式串与主串的匹配次数,容错不超过三个字符. Solution 枚举每个开始位置,进行暴力匹配,直到失配次数用光或者匹配成功.考虑到容错量很小, ...

  5. POJ 3264 Balanced Lineup 【ST表 静态RMQ】

    传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total S ...

  6. ST表解决RMQ问题

    RMQ问题: RMQ(Range Minimum/Maximum Query),区间最值查询.对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间 ...

  7. ST表 求 RMQ(区间最值)

    RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...

  8. ACM/ICPC 之 暴力打表(求解欧拉回路)-编码(POJ1780)

    ///找到一个数字序列包含所有n位数(连续)一次且仅一次 ///暴力打表 ///Time:141Ms Memory:2260K #include<iostream> #include< ...

  9. ST表(离线RMQ)

    离线RAQ时,预处理为O(n*lgn),查询为O(1)的算法,比较有意思的一种算法 放个模板在这可以随时看 //ST表(离线) //预处理 O(n*lgn) , 查询 O(1) #include &l ...

随机推荐

  1. node开发一个接口详细步骤

    最近在做后台系统改版,由于目前接口还没出来,就自己用nodejs写了个简单的接口. 我这里用的是nodejs+mysql的 这里不讲nodejs和mysql的安装.这些基础略过. 首先创建文件夹.cd ...

  2. em、rpx和px的换算

    rpx:对于小程序开发,所用的单位都是rpx,而不论哪个型号的手机,屏幕宽度都是750rpxrpx与px的转换,根据设计稿换算例如:设计稿750px宽度,ps上量出或者标出的宽度是多少,那么就定义多少 ...

  3. 启动ZOOKEEPER之后能查看到进程存在但是查不到状态,是因为。。。

    一般我们在启动ZOOKEEPER之后能查看到进程并且能查到每个节点的状态,但是新手偶尔会遇到查不到状态的问题,这里主要说一下我自己遇到的问题. 是因为myid重复了.... 错误:总共三个节点,mas ...

  4. Java开发桌面程序学习(10)——css样式表使用以及Button使用

    css 样式表使用 javafx中的css样式,与html的有些不一样,javafx中的css,是以-fx-background-color这种样子的,具体可以参考文档JavaFx css官方文档 简 ...

  5. alert(1) to win 8

    function escape(s) { return '<script>console.log("' + s.toUpperCase() + '")</scri ...

  6. 前端每日实战:21# 视频演示如何用纯 CSS 创作文本滑动特效的 UI 界面

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/QrxxaW 可交互视频教程 此视频 ...

  7. JVM加载class文件原理

    装载的概念 所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的class对象的过程. Java中类装载器装载类到虚拟机 在Java中,类装载器把一个类装入Ja ...

  8. 610K图纸打印新版增值税发票不完整的调整方法 黑盘红盘都兼容

    新版增票页面设置增票向下0.8向右-10,5刻度进纸测试 向右调整可能会有些出入 根据情况微调即可. 下面为黑盘的设置 可与上面兼容

  9. UML建模重点圈划

    面向对象的特征 *P9*>封装性>继承性>多态性>传递性 建模语言的三个类别 *P14*> - 非形式化的.半形式化的和形式化的 UML 特点*15*主要有三个特点:&g ...

  10. Centos6安装mysql

    此处安装的是MariaDB,介绍如下: MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可. 开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将My ...