没用的话:好像好久没更博了,无聊就讲讲算法吧(主要找不到水题)。

感觉针对初学者,老师教这个算法时没怎么懂,最近(大概1、2个月前吧)老师又教了lca(最近公共祖先,额,可以百度,我就不讲了,可能以后会再写一篇博客关于这个)讲到lca转RMQ才又回来认真复(xue)习(xi)。大概搞懂了,本质是dp。

认识RMQ:

要学习RMQ,首先要知道RMQ问题是什么吧?

RMQ简单来说就是求区间的最大值(最小值)。

什么?没懂!

举个栗子:

1  -2  9  10  15  38  -9

这里有 7 个数(随便输的),RMQ就是用来查询这些数中的最大值(最小值),但是是区间的。比如查询  [1,3]  这个区间的最大值 就是  9 这个值 .

这样讲应该懂了吧。

暴力解法:

其实这样的题目可以直接暴力对吧,一重循环枚举区间就好了。

但是如果有多个询问效率显然就低了很多,因为可能会重复计算。

所以会有人想到dp吧。

RMQ解法:

而RMQ的一解法就是一个神奇dp。(当然你也可以线段树)

RMQ感觉很少用到,但这个dp思想却能有很大启发! (具体来讲,这个思想是倍增)

进入正题——RMQ(以下以求最大值为例)

F[i,j]表示 从 i 开始 到i+2j -1(可能不是很清楚,是二的 j 次方再减一)这个区间中的最大值

什么?为什么要用 2这么奇怪的东西? 这就是RMQ的神奇

然后就是初始值了 显然 F[i,0]=a[i](原始数组) 对吧 因为 2等于1 一个数的区间最大值肯定就是这个数 你总不会说 [2,2] 这个区间的最大值在[3,3]这个区间吧?

辣么状态转移方程呢?

F[i,j]=max(f[i,j-1],f[i+2j-1,j-1])

这么啪给你肯定是不懂的

自己画了张图:

假如要求绿色这段区间的最大值,实际上主要这段蓝色这段区间的最大值和红色这段区间的最大值就可以了对吧,

绿色这段区间的最大值就会等于max(蓝色最大值,红色最大值)

因为dp是递推而来的,所以蓝色最大值和红色最大值是已知的,

所以方程就是 F[i,j](这里指[1,4]这个区间,所以i=1,j=2)=max(f[i,j-1](指[1,2]这个区间,所以i=1,j-1=1)  ,f[i+2j-1,j-1](指[3,4]这个区间,所以i=1+21=3   j-1=1))

可能不好理解,j可以抽象为[1,4] 4个数, j-1 就为2个数 ,已知 2 个连续的 2个数的区间 那么就能求出1个 4个数的区间

大概代码:

for i= --> n
f[i,]=a[i]; //初始化
for j= --> log2(n)
for i= --> n
f[i,j]=max(f[i,j-],f[i+( << (j-))]);// RMQ状态转移方程

如果你问为什么j放外循环,那就是对RMQ还不够理解。

如果j放了内循环,那么求解顺序就变成了 f[1..n,1]...f[1..n,log2(n)] 这样就不会先求出 2 个连续的 2个数的区间的最大值,也就不能dp了。

上面讲完了RMQ的dp之后捏,会发现还缺了一个步骤,预处理完当然是查询辣~

我萌已经预处理出了 f[i,j] 表示 原数组a[] 中从 下标为 i 开始之后的 2j  个数中的最大值。

也许很抽象,还是举个栗子。

比如

1  -2  9  10  15  38  -9  (我会跟你说这是上面的栗子是因为我想不出栗子了么)

辣么 f[1,1] 就是代表  [1,2] 这个区间的最大值 也就是 f[1,1]=1。

f[1,2] 就是代表  [1,4] 这个区间的最大值 也就是 f[1,2]=10。

辣么 f[] 数组所代表的含义应该很清楚了吧...所以肿么查询

我萌需要找到两个区间,而这两个区间合起来后能包含整个查询区间而且不包含除查询区间的数。

还是上面辣个栗子

比如查询 区间 [2,6] 要肿么查询,我萌就找两个区间,   [2,5] 和 [3,6]这两个区间

因为是查询最大值所以就是两个区间有交集也没什么关系。

辣么问题来了,为什么是这两个区间而不是其他的两个区间捏。

为了能把区间用 f[i,j] 的方式表示出了,我萌可以发现 区间 [2,5] 实际上就是 区间 [,2+22-1] 辣么这个区间的最大值就可以用 f[2,2] 表示

同样的 区间 [3,6] 也可以表示成 f[i,j]  为 f[3,2] 这样只需要O(1) 就查询好了

辣怎么去找这两个区间?简单理解是这样的,因为要包含查询区间又不允许包含除查询区间的数。所以这两个区间必然是这样的 (设查询区间 [l,r] )

[l,x]   [r-(x-l),r]   可以说这个 x值只要满足 (l<=x<=r)且(x>=(r-l)/2) 就可以,但是为了满足 f[i,j] 就必须保证  (x-l+1) 为2的  k  (k为自然数)次方(不理解的话拿上面的栗子算一下)

所以用log2 就能找到一个k值, k=log2(r-l+1)  (取整)    (r-l+1)是查询区间的长度,log2后就得到了必然满足 (x-l+1) 为2的某次方的条件。

辣么就可以用k来表示 f[] 数组了   两个区间 的最大值为  f[l,k] 和 f[r-2k+1,r] 所以ans=max(f[l,k],f[r-2k+1,r])。

最后,也许你会有点奇怪...为什么非得用2j的来表示f[]数组。我觉得两个原因吧。

一是dp的需要,用2j表示就可以在O(1)的时间里进行比较,因为只要比较两个区间,而3j需要比较三个区间。(也许我瞎bb其实也不是很清楚)

二是可以利用电脑二进制的属性,利用位运算更快的求出2j的值。

大概就讲这么多,希望有帮助。

RMQ应用还是不多,也就大概是lca ,建议学的是思路.

上次留下的大坑啊...过了将近半年才回来补...

谈谈RMQ问题的更多相关文章

  1. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  2. 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  3. 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  4. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  5. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  6. 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  7. 谈谈一些有趣的CSS题目(四)-- 从倒影说起,谈谈 CSS 继承 inherit

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  8. 谈谈一些有趣的CSS题目(五)-- 单行居中,两行居左,超过两行省略

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  9. 谈谈一些有趣的CSS题目(六)-- 全兼容的多列均匀布局问题

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

随机推荐

  1. 支付宝app支付提示 系统繁忙,请稍后重试

    v2版本的支付宝支付,无论怎么调试返回的都是系统繁忙,请稍后重试提示.经过对给的示例代码的仔细研究,最后发现是由于老版本的sign_type 不加入签名计算,而新版本的支付签名它是加入签名计算的.供大 ...

  2. 【Double】double精度问题和int、long除不尽取舍问题

    看了老半天,真心没搞懂,留下几篇文章,后面继续跟进吧.... 一.如何理解double精度丢失问题? - 知乎 https://www.zhihu.com/question/42024389/answ ...

  3. mongoose连接数据库的两种形式

    不废话,直接 ---------------------- .如果你的应用程序只使用一个数据库, 应该使用 mongoose.connect. 如果您需要创建额外的连接,使用 mongoose.cre ...

  4. jsp页面上读取MySQL数据库datetime时间显示问题

    mysql数据库中时间字段选用了datetime,如果通过java实现在jsp页面上显示时间为"年-月-日  时:分"等格式,那么如下代码就会有不同的结果! 实体类中两个变量: p ...

  5. MySQL日期时间字段

    mysql支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: DATETIME DATETIME 用于表示 年月日 时分秒,是 DATE和 ...

  6. java 字符串解析为json 使用org.json包的JSONObject+JSONArray

    参考: https://blog.csdn.net/xingfei_work/article/details/76572550 java中四种json解析方式 JSONObject+JSONArray ...

  7. USB 3.0:那些你需要知道的事

    在过去14年来,通用串行总线(USB)已成为计算机和外部设备之间的标准接口.不管是移动硬盘.相机.鼠标.键盘.打印机,还是扫描仪,它们和计算机之间的数据传输一般均采用USB线.USB接口也的确是“通用 ...

  8. SQL基础一

    一.什么是SQL? SQL是结构化查询语言 SQL使我们有能力访问数据库 SQL是一种ANSI的标准计算机语言 二.SQL能做什么? SQL 面向数据库执行查询 SQL 可从数据库取回数据 SQL 可 ...

  9. python全栈开发从入门到放弃之字符编码

    一 了解字符编码的知识储备   1. 计算机基础知识(三幅图)       2. 文本编辑器存取文件的原理(nodepad++,pycharm,word) 打开编辑器就打开了启动了一个进程,是在内存中 ...

  10. ruby项目文件上传功能实现

    这里我将从视图.控制器各个层面进行讲解. rails 提供了文件上传功能,可以直接进行下面的编码 <%= form_for :document, :html =>{:multipart = ...