RMQ(Range Minimum/Maximum Query),即区间最值问题。

对于长度为 n 的数列 A ,回答若干查询 RMQ(A,i,j)(i,j<=n) ,返回数列 A 中下标在 i,j 里的最大(小)值。

相关算法

  1. 朴素(搜索),时间复杂度:\(O(n)-O(q \times n)\) ,在线;
  2. 线段树,时间复杂度:$O(n)-O(q\times logn) $,在线;
  3. ST(动态规划),时间复杂度:\(O(n\times logn)-O(q)\),在线;
  4. RMQ标准算法,先规约为LCA,再规约成约束RMQ ,时间复杂度:\(O(n)-O(q)\),在线。

ST 算法

假设当前题目要求区间最小值,我们令 dp[i][j] 代表从 i 开始,长度为\(2^{j}\)这段区间的最小值。

于是便有:\(dp[i][j]=min(dp[i][j-1],dp[i+^{j-1}][j-1])\)

分析可知,\(dp[i][j-1]\)代表从 i 开始,长度为\(2^{j}\)区间一半中的最小值,而 \(dp[i+2^{j-1}][j-1]\)即为区间的另一半。

即为区间的另一半。

最终(从下往上看):

\(dp[0][*]\) \(dp[1][*]\) \(dp[2][*]\) \(dp[3][*]\) \(dp[4][*]\) \(dp[5][*]\) \(dp[6][*]\) \(dp[7][*]\)
\(dp[*\)][3] \(1\)
\(dp[*\)][2] \(1\) \(1\) \(1\) \(5\) \(2\)
\(dp[*][1]\) \(3\) \(1\) \(1\) \(5\) \(7\) \(6\) \(2\)
\(dp[*][0]\) \(4\) \(3\) \(1\) \(5\) \(7\) \(8\) \(6\) \(2\)

预处理

根据状态转移方程,首先指定当区间长度为\(2^{0}\)时的各初始值,随后推出后面的结果。

void ST_Init(const vector<int> &A) {
int n=A.size();
for (int i=0; i<n; i++)
dp[i][0]=A[i];
for (int j=1; (1<<j)<=n; j++)
for (int i=0; i+(1<<j)<=n; i++)
dp[i][j]=min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
}

查询

预处理出整个 dp 数组以后,查询操作很简单,令 k 为满足\(2^{k} \leq R-L+1\)的最大整数,则以 L 开头、以 R 结尾的两个长度为\(2^{k}\)的区间合起来即覆盖了查询区间 [L,R]

int RMQ(int L, int R) {
int k=0;
while ((1<<(k+1))<=R-L+1) k++;
return min(dp[L][k], dp[R-(1<<k)+1][k]);
}

嗯!怎么说呢?感觉线段树在这种类型的题目中好像是最万能的方法了。

无论是 [点修改+查询] 还是 [区间修改+查询] ,它都可以做到 \(O(logn)\)的复杂度,而且在线段树中我们也可以维护好多东西(区间和、最值等等)。

对于一维中的线段树,我们想要查询某个区间的最值,首先就应该建树咯~(具体方法省略

而在查询时,我们可以从根节点向下递归搜索,如下图,假设查询区间为 [2,6]

[2,6] 这一个大区间分解为不相交的三个小区间 [2,3]、[4,5]、[6] ,而最终的结果便由这三个节点中所维护的信息决定的!

我们假设查询还是区间最小值,于是最终的结果为\(\min(1,7,6)=1\)

线段树可以解决普通的 [点/区间] 修改+查询 ,当然它也可以解决 树中的路径权值 修改+查询(树链剖分)。

『数据结构』RMQ问题的更多相关文章

  1. 『图论』LCA 最近公共祖先

    概述篇 LCA (Least Common Ancestors) ,即最近公共祖先,是指这样的一个问题:在一棵有根树中,找出某两个节点 u 和 v 最近的公共祖先. LCA 可分为在线算法与离线算法 ...

  2. 『TensotFlow』RNN中文文本_下_暨研究生开学感想

    承前 接上节代码『TensotFlow』RNN中文文本_上, import numpy as np import tensorflow as tf from collections import Co ...

  3. 『TensotFlow』RNN中文文本_上

    中文文字预处理流程 文本处理 读取+去除特殊符号 按照字段长度排序 辅助数据结构生成 生成 {字符:出现次数} 字典 生成按出现次数排序好的字符list 生成 {字符:序号} 字典 生成序号list ...

  4. 『PyTorch』第三弹重置_Variable对象

    『PyTorch』第三弹_自动求导 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Varibale包含三个属性: data ...

  5. 『Json』常用方法记录

    json模块可以把字典结构改写为string然后保存,并可以反向读取字典 pickle模块则可以持久化任意数据结构 但是即使同样是字典数据结构,两个包也是有差别的, json字典value不支持其他对 ...

  6. 『StabilityGuide』| 10+位阿里技术专家共同发起稳定性知识库开源项目

    我们穿过山和大海,也见过人山人海.我们见过各类故障,也排过千雷万险.这一次,不如我们一起,开启稳定性的探索之旅.让无法解决的问题少一点点,让世界的确定性多一点点. 无论是前端业务的开发者,还是后端架构 ...

  7. 『AngularJS』$location 服务

    项目中关于 $location的用法 简介 $location服务解析在浏览器地址栏中的URL(基于window.location)并且让URL在你的应用中可用.改变在地址栏中的URL会作用到$loc ...

  8. [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装

    [原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...

  9. JS 中通过对象关联实现『继承』

    JS 中继承其实是种委托,而不是传统面向对象中的复制父类到子类,只是通过原型链将要做的事委托给父类. 下面介绍通过对象关联来实现『继承』的方法: Foo = { // 需要提供一个 init 方法来初 ...

随机推荐

  1. Python开发专属壁纸下载与轮换程序

    本人对于壁纸一直偏佛系,不爱特意去找一堆壁纸.因此用Python简单地搞了一个自动下载壁纸,定时随机轮换的功能来自娱自乐,顺便分享给大家. 原文链接:https://www.codernice.top ...

  2. 网页布局——table布局

    table 的特性决定了它非常适合用来做布局,并且表格中的内容可以自动居中,这是之前用的特别多的一种布局方式 而且也加入了 display:table;dispaly:table-cell 来支持 t ...

  3. linux上安装LAMP笔记

    B哥最近在参加比赛,需要把一个php项目部署到服务器上,故此在linux上安装LAMP环境,用于部署项目,第一次安装,做点儿笔记记录一下. 安装条件: Redhat或者CentOS linux环境已装 ...

  4. 主动降噪(Active Noise Control)

    智能耳机 人机交互 智能声学终端 智能耳机 智能音箱 智能听力器 喇叭单体 动圈喇叭 新材料 DLC 石墨烯 陶瓷单位 吸音材料 智能芯片 阵列式麦克风 声纹传感器 演算法 降噪算法 智能听力保护 A ...

  5. springboot配置logback日志

    springboot配置logback日志 java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日 ...

  6. 攻防世界(XCTF)逆向部分write up(一)

    晚上做几个简单的ctf逆向睡的更好 logmein elf文件 ida看看main函数伪代码 void __fastcall __noreturn main(__int64 a1, char **a2 ...

  7. Java的事件自定义事件学习

    课程设计要做一个游戏,由于对C++不是很熟悉,老师也准许使用java 或者其他的语言,在.net我学过事件,一种委托回调,但是在java 我不是很了解,应该原理都相同吧! 游戏大致是这样的,现在这在写 ...

  8. Cocos2d-x 学习笔记(11.7) Repeat RepeatForever

    1. 成员变量 Repeat: unsigned int _times; //create参数 unsigned int _total; //执行的次数 float _nextDt; //startW ...

  9. 使用js json/xml互相转换

    <html> <head> <title>json与xml互转</title> <script type="text/javascrip ...

  10. myeclipse 在web-inf/lib中导入包

    今天用myeclipse的时候发现无法在web-inf/lib导入包,如果直接在工程上导入,则进入了一个referenced libraries的文件夹里,而web-inf/lib里面是没有jar包的 ...