RMQ问题:对于长度为N的序列,询问区间[L,R]中的最值

RMQ(Range Minimum/Maximum Query),即区间最值查询

常见解法:

1.朴素搜索

2.线段树

3.DP

4.神奇的笛卡尔树(https://www.cnblogs.com/jklongint/p/4777448.html?utm_source=tuicool)

1.朴素搜索

max=a[L];
for(int i=L+1;i<=R;i++)if(max<a[i])max=a[i];
}

2.线段树:https://www.cnblogs.com/jason2003/p/9676729.html

大概就是玩区间,将一个区间分为很多个小区间,分治的思想。

public class TestE {public static void main(String[] args) {int[]a= {3,4,5,1,2};SenLin sl=new SenLin(a);sl.buildTree(0, 4, 1);System.out.println(sl.search(0, 4, 1));}}
class SenLin{Tree[]N=new Tree[300];int[] values;public SenLin(int[]values) {this.values=values;}public void buildTree(int l,int r,int u) {N[u]=new Tree();N[u].l=l;N[u].r=r;if(l==r) {N[u].max=values[l];return;}buildTree(l,r+l>>1,2*u);buildTree((r+l>>1)+1,r,2*u+1);N[u].max=Math.max(N[2*u].max, N[2*u+1].max);}public int search(int l,int r,int u) {if(N[u].l==l&&N[u].r==r)    return N[u].max;    if(r<=N[2*u].r)    //在左孩子的范围里    return search(l,r,2*u);    if(l>=N[2*u+1].l)//在右孩子的范围里return search(l,r,2*u+1);    int mid=(N[u].l+N[u].r)>>1;    return Math.max(search(l,mid,2*u),search(mid+1,r,2*u+1));}
}
class Tree{int l;int r;int max;
}

3.DP

3.1预处理(时间复杂度O(nlogn))

建立dp数组,dp[i][j]表示从i开始长度为2j的区间中的最值(DP的状态)。当dp[i][0]就是从i开始长度为1的区间,就是它本身。(DP的初始值)

目的是将求从i长度为2j的大问题可以分为两个长度为2(j-1)的小问题,即[i,i+2j-1-1],[i+2j-1,i+2j-1+2j-1-1]=[i+2j-1,i+2j-1]。

因为r-l+1这个区间长度可能不是2的整数次幂,但是可以有重叠的部分,并不影响。

则可以得到:dp[i][j]=max(dp[i][j-1],dp[i+2j-1][j-1])(DP的状态转移方程)

//dp初始条件
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-1)<=N;i++)dp[i][j]=max(dp[i][j-1],dp[i+(1<<j-1)][j-1]);

此处注意内外层循环,这个填表过程相当于竖着填表。

3.2查询(时间复杂度O(1))

我们回到题目:对于长度为N的序列,询问区间[L,R]中的最值,假设这里我们需要的是最大值,毋庸置疑,rmq=dp[L][m],就是从L开始,长度为2m,r-l+1=2m解得m=log2(r-l+1)问题是前文中提到得l-r+1不一定是2的整数次幂.

所以我们将其转换为求两个区间这两个区间为[l,l+2k-1][r-2k+1,r],一个确保了开头为l,另一个确保了结尾为r,得问题:rmq=max(dp[L][k],dp[r-2k+1][k]),这个2k可以是[l,r]之间重叠的部分,保证覆盖[l,r]之间所有的数。

我们要维护的两个区间是[l,l+2k-1][r-2k+1,r],为了保证覆盖[l,r]之间所有的数就要满足:l+2k-1>=r-2k+1

化简得:k>=log2(r-l+1)-1,所以k=log2(r-l+1)-1时,可以满足求得[l,r]之间得最值问题

int k=log2(r-l+1)-1
rmq=max(dp[l][k],dp[r-(1<<k)+1][k]);

static RMQ相关推荐

  1. 算法编程Algos Programming

    算法编程Algos Programming 不同算法的集合,用于编程比赛,如ACM ICPC. 算法按主题划分.大多数算法都可以从文件中按原样运行.每种算法都有一个参考问题,并对其时间和空间复杂度作了 ...

  2. 【蓝桥】第十一届软件类校内模拟赛(一)

    前言 本题解为第十一届软件类校内模拟赛个人题解,但非官方满分题解,因此,可能存在下列问题 题意理解错误,导致答案错误. 代码中存在一些问题,导致答案错误. 算法复杂度的分析有误,导致不能在规定时间内得 ...

  3. RMQ+1/-1算法

    RMQ+1/-1问题要求数列中相邻两个元素相差+1或-1.利用这个限定条件可以使该算法复杂度总体上达到<O(n),O(1)>.具体做法是: 1) 设数列A的大小为n,先对数列A分组,每组大 ...

  4. 【BZOJ3700】发展城市 [LCA][RMQ]

    发展城市 Time Limit: 20 Sec  Memory Limit: 512 MB [Submit][Status][Discuss] Description 众所周知,Hzwer学长是一名高 ...

  5. poj 3264 Balanced Lineup RMQ问题 线段树

    For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...

  6. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MB Submit: 1594  Solved: 520 [Submi ...

  7. RMQ(Range Minimum Query)

    2019独角兽企业重金招聘Python工程师标准>>> 问题 RMQ问题是求给定区间中的最值问题.对于长度为n的数列A,回答若干查询RMQ(A, i, j).返回数组A中下标在[i, ...

  8. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  9. RMQ+1/-1算法 [转]

    [转] http://blog.csdn.net/ljsspace/article/details/6659517 RMQ+1/-1问题要求数列中相邻两个元素相差+1或-1.利用这个限定条件可以使该算 ...

  10. 约束rmq_约束RMQ - osc_jor8x3el的个人空间 - OSCHINA - 中文开源技术交流社区

    不知道为什么网上找不到太多相关的资料,所以写一个小总结,并附有能用的代码,抛砖引玉. 约束RMQ,就是RMQ区间必须满足两项之差最大为1,采用ST表的话,这时候有O(n)建表,O(1)查询的优秀复杂度 ...

最新文章

  1. 一套简单通用的Java后台管理系统,拿来即用,非常方便(附项目地址)
  2. js实现焦点进入文本框内关闭输入法:imeMode
  3. 龙芯linux内核移植开发板,基于国产龙芯GS32I的开发板的设计与嵌入式Linux的移植...
  4. 【CyberSecurityLearning 57】XSS
  5. VS2010代码提示功能配置:Visual Assist X 10.7.1912.0
  6. python数据挖掘学习笔记】十六.逻辑回归LogisticRegression分析鸢尾花数据
  7. DataSet之间的赋值
  8. linux shell if命令参数说明
  9. AI CC2017安装后,安装目录里找不到amtlib.dll文件的问题
  10. synctoy 远程同步_使用SyncToy将任何文件夹同步到Dropbox
  11. Java 类详解 9章
  12. 前端优化 | DOSM Web项目优化分析 ( 附解决方案及代码)
  13. 工程师的基本功是什么?该如何练习?
  14. java学生成绩管理系统类图,学生成绩管理系统的用例类图
  15. python主函数调用格式_Python的模块与函数
  16. 证书文件编码格式介绍
  17. Spark与Iceberg整合查询操作-查询快照,表历史,data files Manifests 查询快照,时间戳数据...
  18. 计算机除尘 注意事项,电脑除尘要注意
  19. Vue.js的组件化开发
  20. C语言调用so动态库的两种方式

热门文章

  1. Python爬虫开发【第1篇】【正则表达式】
  2. MySQL全量备份和增量备份脚本
  3. jQuery Validate验证框架(转载)
  4. 为您详细比较三个 CSS 预处理器(框架):Sass、LESS 和 Stylus
  5. System.Windows.Forms.TreeView
  6. 用Hough投票做物体检测(续)
  7. 科罗拉多州立大学计算机科学,科罗拉多州立
  8. 上海自考计算机及应用,上海交通大学--计算机及应用(独立本科080901)
  9. 递归经典案例汉诺塔 python实现_python实现汉诺塔递归算法经典案例
  10. 拓端tecdat|R语言基于线性回归的资本资产定价模型(CAPM)