实用算法实现-第 9 篇 RMQ问题

RMQ问题(超详细!!!) 0x01 介绍 **RMQ (Range Minimum/Maximum Query)**问题是指:对于长度为nnn的数列AAA,回答若干询问RMQ(A,i,j)(i,j<=n)RMQ(A,i,j)(i,j<=n)RMQ(A,i,j)(i,j<=n),返回数列AAA中下标在i,ji,ji,j里的最小(大)值,也就是说,RMQ​问题是指求区间最值的问题。 0x02 朴素算法 最简单... 阅读详情

9.1    RMQ问题

RMQ(Range Minimum/Maximum Query)问题,就是对于给定数组,在其下标范围[i, j]内给出的最小值(或最大值,下文都称最小值)的问题。

RMQ和LCA问题可以互相转化,一个对RMQ和LCA问题的总结如下表[i]:

 

算法

处理方式

复杂度

备注

转化算法

LCA =>±1RMQ

N/A

O(n)

引理1,规模O(n) - O(2n-1)

RMQ => LCA-CT

N/A

O(n)

引理2,规模不变

朴素算法

LCA-Naive

online

O(n^2) - O(1)

动态规划

RMQ-Naive

online

O(n^2) - O(1)

直接求解

经典算法

LCA-Tarjan

offline

O(na(n))

 

RMQ-ST

online

O(nlogn) - O(1)

 

改进算法

RMQ-ST-Block

online

O(nloglogn) - O(1)

将RMQ-ST分段处理

±1RMQ-ST-Block

online

O(n) - O(1)

控制RMQ-ST-Block中分段的段种数,得到O(n)算法。

快速算法

RMQ-Fast

online

O(n) - O(1)

RMQ => LCA-CT => ±1RMQ

折衷算法

RMQ-IT

online

O(n) - O(logn)

线段树直接处理

RMQ-CT-Tarjan

offline

O(na(n))

RMQ => LCA-CT再用LCA-Tarjan解决。


我们可以将一般RMQ的值得应用的算法列表:

算法

处理方式

复杂度

备注

RMQ-IT

online

O(n)-O(logn)

询问不多时,竞赛首选。

RMQ-CT-Tarjan

offline

O(na(n))

由于是离线的,而且还要转化成CT,某些地方不应用。

RMQ-ST

online

O(nlogn)-O(1)

询问多时,竞赛首选。

RMQ-ST-Block

online

O(nloglogn)-O(1)

时间要求特别严格时采用。

 

1.2    Sparse Table算法

RMQ的一个经典的算法是SparseTable(ST)算法。它可以在O(nlgn)的预处理时间后,提供O(1)时间的查询。

定义d[i, j]为下标在区间[i, i+2^j-1]中的数组S的元素的最小值。即:

d[i, j] = min{S[k] | i ≤ k ≤ i+2^j-1}

有:

d[i, j-1] = min{S[k] | i ≤ k ≤ i+2^(j-1)-1}

d[i+2^(j-1), j-1] = min{S[k] | i+2^(j-1) ≤ k ≤ i+2^(j-1)+2^(j-1)-1} =min{S[k] | i+2^(j-1) ≤ k ≤ i+2^j-1}

故此有:

d[i, j] = min{S[k] | i ≤ k ≤ i+2^j-1} = min{d[i, j-1], d[i+2^(j-1),j-1]}

可以观察到区间[i, i+2^j-1]被分为区间[i, i+2^(j-1)-1]和区间[i+2^(j-1), i+2^j-1]。

对于所有{(i, j) | 0 ≤ i ≤ n-1, 0 ≤i+2^j-1 ≤ n-1 }都求出d[i, j]。首先依据定义有d[i, 0] = S[i]。又由于有上述的递推式,所以在已求出d[i, j-1]和d[i+2^(j-1), j-1]的前提下,d[i, j]可以在常数时间内求出。又由于{(i, j) | 0 ≤ i ≤ n-1,0 ≤ i+2^j-1 ≤ n-1} = {(i, j) | 0 ≤ i ≤ n-1-(2^j-1), 0 ≤ 2^j-1 ≤ n-1},所以可以在[0, n-1]区间内遍历2^j-1,并对每个j,求出每个合要求的i对应的d[i, j]。如果采用这种方法,在求解d[i, j]之前,d[i, j-1]和d[i+2^(j-1), j-1]都已经求出,故此求d[i, j]可以在常数时间内完成。由于j有O(lgn)个选择,而对每个j,i有O(n)个选择,故此求出数组d需要的时间是O(n lgn)。

假设要在[i, j]区间内查询最小值,即RMQ(i, j),则令k = max{l | 2^l ≤ (i-j+1)},即k为log(i-j+1)取下限。由此2^k*2 ≥ i-j+2,即i+2^k-1 ≥ j-2^k+1,所以[i, j]可被子区间[i, i+2^k-1]和[j-2^k+1, j]覆盖。而两个区间内的最小值分别是d[i, k]和d[j-2^k+1, k]。所以RMQ(i, j) = min{d[i, k], d[j-2^k+1,k]}。所以任意的查询都可以在O(1)时间内完成。

1.2.1   实例

PKU JudgeOnline, 3264, Balanced Lineup.

1.2.2   问题描述

给出一组数据,求出一个坐标区间内的最大值和最小值的相差范围。

1.2.3   输入

63

1

7

3

4

2

5

15

46

22

1.2.4   输出

6

3

0

1.2.5   分析

       这是经典的RMQ问题,用线段树也可以做。

       可以发现,可以将二维数组d的两维互换,这样可以提高访问速度。

1.2.6   程序

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxNum     50002
int Dmax[16][maxNum];//注意这里为了提高访问速度,将数组的两维互换
int Dmin[16][maxNum];
int cow[maxNum];
int n;
void bulidST()
{
     int k;
     int l;
     int i, j;
     for(i = 0;i < n; i++){
         Dmin[0][i] = cow[i];
         Dmax[0][i] = cow[i];
     }
     for(j = 1;(k = (1<<j) - 1) < n; j++){
         for(i =0; i < n - k; i++){
              l = (k + 1)>>1;
              if(Dmin[j- 1][i] < Dmin[j - 1][i + l]){
                   Dmin[j][i] = Dmin[j - 1][i];
              }else{
                   Dmin[j][i] = Dmin[j - 1][i +l];
              }
              if(Dmax[j- 1][i] > Dmax[j - 1][i + l]){
                   Dmax[j][i] = Dmax[j - 1][i];
              }else{
                   Dmax[j][i] = Dmax[j - 1][i +l];
              }
         }
     }
}
int checkST(int i, intj)
{
     int k;
     int d;
     int RMaxQ;
     int RMinQ;
     k = 0;
     d = 1;
     while(d<< 1 <= j - i + 1){
         d <<= 1;
         k++;
     }
     if(Dmin[k][i]< Dmin[k][j - d + 1]){
         RMinQ = Dmin[k][i];
     }else{
         RMinQ = Dmin[k][j - d + 1];
     }
     if(Dmax[k][i]> Dmax[k][j - d + 1]){
         RMaxQ = Dmax[k][i];
     }else{
         RMaxQ = Dmax[k][j - d + 1];
     }
//   cout << RMaxQ<< " : " << RMinQ << endl;
     returnRMaxQ - RMinQ;
}
int main()
{
     int q;
     int i;
     int l, r;
     scanf("%d%d",&n, &q);
     for(i = 0;i < n; i++){
         scanf("%d",&cow[i]);
     }
     bulidST();
     for(i = 0;i < q; i++){
         scanf("%d%d",&l, &r);
         printf("%d\n",checkST(l - 1, r - 1));
     }
}
本文章欢迎转载,请保留原始博客链接http://blog.youkuaiyun.com/fsdev/article

[i] http://adn.cn/blog/article.asp?id=20

LCA 转 RMQ算法 【总结】 首先,在你看这个算法之前,要确保你理解了RMQ的 ST 算法。 但是不理解没关系啊,提供通道:  点我 声明:这是方便我以后复习用的,所以总结不是特别详细。 LCA - 最近公共祖先:在有根树中,两个节点u和v的公共祖先中距离最近的那个点。 上图理解: 如图,我们想要求出LCA(4,7),LCA(8,6),LCA(5,8)。 用LCA转R 阅读详情

相关推荐

浅谈RMQ算法

前言 RMQ是什么 RMQ算法描述 RMQ算法的不足 RMQ算法例题前言这篇文章,是一篇总结RMQ算法的一篇文章,若有疑问或建议,请于下方留言,谢谢!RMQ是什么?RMQ(Range Minimum/Maximum Query),即区间最值查询。是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。这两个问题是在实际应用中

farandnear的博客 1413

rmq_ST算法

ST算法: 为离线算法,查询最值问题 minn[i][j]表示区间 [i , i+(1<<j)-1] 的最小值,minn[i][j]一定是偶数个数的最小值,所以对它一分为二 状态方程:minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]) 查询[l,r]区间时,区间个数是r-l+1, k为log2(r-...

weixin_30788239的博客 134

【STM32G474实战】RS485通信的DMA优化策略与性能对比

本文深入探讨了在STM32G474微控制器上优化RS485通信的DMA策略。通过对比轮询、中断和DMA三种数据传输方式的代码实现与性能,揭示了DMA在解放CPU、降低占用率方面的巨大优势。文章提供了详细的DMA配置指南、高级应用技巧(如结合空闲中断)以及一个高可靠通信框架的实战思路,旨在帮助开发者构建高效、实时的工业控制系统。

weixin_29268331的博客 303

RMQ算法

RMQ算法(Range Minimum/Maximum Query),即区间最值查询,是一种在线算法。 补充:所谓在线算法就是每次输入可立刻处理一个结果,对比离线算法,离线算法是要知道所有的输入之后才开始处理结果,例如选择排序和插入排序,选择排序是一种离线算法,排序之前要知道所有的待排序元素,而插入排序就不必知道,所以插入排序是一种在线算法。 RMQ算法一般用比较长的时间预处理,预处理时间复杂...

qq_31267769的博客 450

gem5 run parsec2.1 ---- 亲测跑通教程

使用gem5模拟仿真parsec2.1,排除了各种bug,成功跑通,亲测有效!!!

m0_55539563的博客 1546

【同花顺公式编辑教程】第4章 功能函数

本章节主要给出大部分能够运行且常用的同花顺指标编辑器提供的函数。其中,计算类函数不作演示,绘图类函数提供示例及示例运行结果。

LiaoYi2016218的博客 2万+

算法之LCA与RMQ问题

1、  概述 LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先)。 RMQ(Range Minimum/Maximum Query),即区间最值查询,是

zh_qd1014的专栏 1381

实战分享:如何利用svchost进程绕过360防护(附完整Shellcode注入教程)

本文深入解析系统进程安全防护机制,探讨svchost等关键进程的安全特性与防护策略。详细分析安全软件的行为检测和内存保护技术,提供系统加固与监控实践建议,助力企业构建多层次防御体系,有效应对潜在安全威胁。

weixin_30752699的博客 99

【码极客精讲】RMQ算法

我们把f[i,j](j≥1)平均分成两段(因为j≥1时,f[i,j]一定是偶数个数字),从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1))。ST算法(Sparse Table),以求最大值为例,设d[i,j]表示[i,i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最大值时答案就是max(d[a,k], d[b-2^k+1,k]),其中k是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]

liuma88的博客 885

功能安全实战系列12-英飞凌TC3xx锁步核及其自检开发

本文介绍了英飞凌Tricore系列芯片的锁步核(Lockstep Core)功能及其故障注入自检机制。锁步核通过主核和检查核同步执行指令,并比较输出结果来检测硬件故障。文章详细阐述了锁步核的工作原理、使能配置方法以及故障注入自检的实现过程。故障注入测试通过专用寄存器LCLTEST触发,系统会定期自动测试比较器节点,验证锁步核的故障检测能力。当检测到异常时,会触发SMU模块的警报机制。该技术为汽车电子系统提供了重要的功能安全保障。

initiallizer的博客 920

【YOLOv11】006、YOLOv11数据增强策略:Mosaic、MixUp等增强技术原理解析

摘要:YOLOv11在产线缺陷检测中遇到小尺寸瑕疵漏检问题,暴露了训练数据过于"干净"的缺陷。数据增强的核心是提升模型泛化能力,而非简单扩充数据。Mosaic增强通过多图拼接迫使模型处理多尺度目标,需注意边界框裁剪细节;MixUp通过线性插值使决策边界更平滑,但需避免类别冲突。自适应增强策略应随训练进度动态调整强度。实际应用中,需针对小目标、类别不平衡等场景调整增强参数,并确保验证与推理流程一致。数据增强应针对性解决具体问题,而非盲目尝试组合。

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 366

理解RMQ问题和ST算法的原理

1.RMQ问题     RMQ (Range Minimum/Maximum Query):对于长度为n的数组A,回答若干询问RMQ(A,i,j)(i,jRMQ问题是指求区间最值的问题。最简单的方法,就是遍历数组直接搜索,但是这种方式时间复杂度是O(n)。对于数组长度较大,性能要求高的场景不适用。 2.ST(Sparse Table)算法 ST算法是一种更加高效的算法,以O(nlog

aty 4172

Ros入门 (十)----激光雷达避障 简易实现

本篇文章通过订阅/scan话题获取障碍物的距离信息,达到避障目的,提供部分代码,仅供参考。

weixin_51157015的博客 1万+

POJ 3264 RMQ问题 ST算法

因为之前都是线段树解决RMQ问题,省脑子……(因为写的顺手)…… 但是因为RMQ毕竟常数大,而且其实程序还相对ST要长…… 以前写过ST算法,但是因为每次都在纠结到底+1 呢,还是-1呢, 边界问题处理的我蛋都碎了好几次,这次重新学习了一下ST(sparse table)算法,好好的处理了这些问题的理解。 ST算法:  解决RMQ问题。 RMQ问题: 区间最大值,最小值问题…

ACMer不要报考高校代码为13627的移通学院! 473

Qt/C++编写自定义控件42-开关按钮

一、前言 从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ、360卫士、金山毒霸等,都有很多开关控制一些操作,在Qt widgets应用项目上,在项目中应用些类似的开关按钮,估计也会为项目增添不少新鲜感。 总结了大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好...

Qt/C++视频监控/推流/物联网/大屏系统/自定义控件/UI定制/输入法 3327

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ST算法解决RMQ问题

RMQ问题 简单说就是求区间最值问题,若是简单的单次询问或者是区间长度很短的询问,可以用暴力的方法来实现,但面对大数据的时候此方法必然超时,这里介绍O(nlogn)预处理,O(1)查询的ST算法。  ST算法 ST的高效在于O(nlogn)的时间预处理,O(1)的时间来查询。其主要思想就是将所求的区间化为两个小区间,这两个区间的长度正好是2的k次幂,总长度正好覆盖[l,r],得到的结果就是所...

Ever_glow的博客 640

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

RMQ问题之ST算法

RMQ(Range Minimum/Maximum Query)问题,即区间最值问题。也就是给出一个数列A1到An,同时给出若干次查询,query(l,r),要求我们快速准确的给出该区间内数列的最值。 显然,对于这种在线查询的问题,暴力情况下,n次查询,每次都要比较所给区间的元素以求出最值,复杂度是相当高的。为了优化解法,一般采用线段树区间查询或者ST算法来解决。最初接触RMQ之ST算法,是学完...

昂昂累世士的博客 344

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

RMQ 算法

看了一些别人的blog,但是我这次不想做大自然的搬运工——农夫山泉。我想写的接地气一点,别人一眼能看懂。 先引入话题吧!给你一个数组 ,其中有N个数字,现在给你一次询问,给你区间[l ,r],问你在这个区间内的最大值或最小值为多少? 我们就解决这么一个问题,这就是RMQ的精髓。RMQ算法的作用就是快速求一个区间中的最大值或者最小值。非常适合区间求最值。 OJ题目...

Cheney的博客 461

约束rmq_客户端基本不用的算法系列:RMQ问题 ST 算法

客户端基本不用的算法系列:RMQ问题 - ST 算法今天的算法可能有点难,但是如果我们只需要会使用 RMQ 问题的 ST 算法模板,这种程度就已经可以了!因为 RMQ 问题除了最优解的 ST 算法,剩下的都是高级数据结构的应用,例如:线段树、树状数组、Splay、Treap 甚至是主席树(额,我什么都没有暗示,业界就是这个名字)。好了今天我们从两个角度来解决这个问题。ST 算法和线段树。...

weixin_42546508的博客 213

约束rmq_区间RMQ问题

简介RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。RMQ(Range Minimum/Maximum Query),即区间最值查询,这是一种在线算法,所谓在线算法,是指用户每次输入一个查询,便马上处理一个查询...

weixin_39643244的博客 274

RMQ的ST算法

RMQ 即 range maximum/minimum query   1、朴素(即搜索),O(n)-O(qn) online。   2、线段树,O(n)-O(qlogn) online。   3、ST(实质是动态规划),O(nlogn)-O(1) online

jxy859的专栏 704

RMQ问题的ST算法实现(详细解析+图片演示+ST模板代码)

Sparse Table算法 解决RMQ问题c++实现+图文解析+模板

ylh的博客 1005

ST算法处理RMQ

​  ST算法是基于倍增原理的,常用于求解最值区间查询(Range Minimum/Maximum Query,所以也成为RMQ问题),这是一种离线算法。

qq_74289134的博客 937
上一篇: 实用算法实现-第 8 篇 后缀树和后缀数组 [4 最长回文子串]
下一篇: 实用算法实现-第 10 篇 动态规划
存储李希
博客等级 码龄15年 418粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值