一、简介

RMQ是询问某个区间内的最大值或最小值,暴力解法对每个询问区间用循环找最值,当n、q>10000会TLE。

常用RMQ的求解方法——ST算法。

ST算法通常用在要多次询问一些区间的最值的问题中。它可以做到O(nlogn)的预处理,O(1)回答每个询问。

使用ST算法的条件是无修改,因此它适用于没有修改并且询问次数较多(10^6级别甚至更大)的情况。

优点:代码短,效率高,实现简单

缺点:适用性差

二、ST算法流程

预处理:

ST算法的原理实际上是动态规划,我们用a[1...n]表示一组数。设f[i, j]表示从a[i]到a[i + 2j - 1]这个范围内的最大值,也就是以a[i]为起点连续2j个数的最大值。由于元素个数为2j个,所以从中间平均分成两部分,每一部分的元素个数刚好为2j-1个,也就是说,把f[i,j]分为f[i, j-1]和f[i + 2j-1, j-1],如下图:

举个栗子吧——如下图所示

整个区间的最大值一定是左右两部分最大值的较大值,满足动态规划的最优化原理,分析得到状态转移方程:

f[i][j] = max(f[i][j - 1], f[i + 2j-1][j - 1]),边界条件为f[i][0] = a[i],这样就可以在O(nlogn)的时间复杂度内预处理f数组。


for(int j=;j<=LN;j++)

  for(int i=;i+(<<j)-<=n;i++)

    f[i][j]=max(f[i][j-],f[i+(<<(j-))][j-]); // <<左移运算符,优化时间常数

询问

若我们要询问区间[li, ri]的最大值,则先求出最大的x满足2x(此处为2的x次方)≤ ri - li + 1,推出x=log2(ri-li+1)

那么区间[li, ri]=[li, li+2x-1]U[ri-2x+1, ri] ,如下图所示:

ans = max(f[li][x], f[ri–2x +1][x]);

两个区间的元素个数都为2x,所以[li, ri]的最大值为max(f[li][x], f[ri - 2x + 1][x]),可以在O(1)内计算出来。虽然这两个区间有交集,但是对于求区间最值来说没有影响,这就是ST算法只适用于求区间最值的原因。

技巧:

因为cmath库中的log2函数效率不高,所以除了调用log2函数外,通常还会使用O(N)递推预处理出1~N这N种区间长度各自对应的k值。具体地,设lg[d]表示log2d下取整,log2d=log2((d/2)*2)=log2(d/2) + 1则lg[d] = lg[d/2]+1。

lg[]=-;//为了lg[1]=0;
for(int i=;i<=n;i++)
lg[i]=lg[i>>]+;// >> 右移运算符,优化时间常数

那么再来看一道例题吧——

1541:【例 1】数列区间最大值

【题目描述】

输入一串数字,给你 M 个询问,每次询问就给你两个数字 X,Y,要求你说出 X 到 Y 这段区间内的最大数。

【输入】

第一行两个整数 N,M 表示数字的个数和要询问的次数; 接下来一行为 N个数; 接下来 M行,每行都有两个整数 X,Y。

【输出】

输出共 M行,每行输出一个数。

【输入样例】

10 2

3 2 4 5 6 8 1 2 9 7

1 4

3 8

【输出样例】

5

8


RMQ问题(超详细!!!)的更多相关文章

  1. 【转】(超详细)jsp与servlet之间页面跳转及参数传递实例

    初步学习JavaEE,对其中jsp与Servlet之间的传值没弄清楚,查看网上资料,发现一篇超详细的文章,收获大大,特此记录下来.具体链接:http://blog.csdn.net/ssy_shand ...

  2. 超强、超详细Redis数据库入门教程

    这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...

  3. Github上传代码菜鸟超详细教程【转】

    最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...

  4. WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码

    转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...

  5. [转]超详细图解:自己架设NuGet服务器

    本文转自:http://diaosbook.com/Post/2012/12/15/setup-private-nuget-server 超详细图解:自己架设NuGet服务器 汪宇杰          ...

  6. GitHub超详细图文攻略

    GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git 分类: 转载2014-03-25 21:10 10641人阅读 评论(2) 收藏 举报 GitHubbr ...

  7. 超详细的Xcode代码格式化教程,可自定义样式。

    超详细的Xcode代码格式化教程,可自定义样式. 为什么要格式化代码 当团队内有多人开发的时候,每个人写的代码格式都有自己的喜好,也可能会忙着写代码而忽略了格式的问题.在之前,我们可能会写完代码后,再 ...

  8. Struts2+Spring4+Hibernate4整合超详细教程

    Struts2.Spring4.Hibernate4整合 超详细教程 Struts2.Spring4.Hibernate4整合实例-下载 项目目的: 整合使用最新版本的三大框架(即Struts2.Sp ...

  9. 超全超详细的HTTP状态码大全(推荐抓包工具HTTP Analyzer V6.5.3)

    超全超详细的HTTP状态码大全 本部分余下的内容会详细地介绍 HTTP 1.1中的状态码.这些状态码被分为五大类: 100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. ...

  10. 安装64位Oracle 10g超详细教程

    安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...

随机推荐

  1. java基础 接口总结

    在java9+版本中,接口的内容可以有: 1.成员变量其实是常量,格式:[public] [static] [final] 数据类型 常量名称 = 数组值:注意: 常量必须进行赋值,而且一旦赋值不能变 ...

  2. Vertx的命令行

    IntelliJ----创建一个运行配置(Application), 用io.vertx.core.Launcher类作为主类,在程序参数输入:run your-verticle-fully-qual ...

  3. 2019 荔枝java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.荔枝等公司offer,岗位是Java后端开发,因为发展原因最终选择去了荔枝,入职一年时间了,也成为了面试官,之 ...

  4. 走一次HashMap的存取

    忘了太多东西,好好复习. 存: if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length;//检查 ...

  5. 【转载】C#中使用Insert方法往ArrayList集合指定索引位置插入新数据

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,在ArrayList集合操作过程中,可以使用ArrayList集合类的I ...

  6. 《微信小程序项目开发实战:用WePY、mpvue、Taro打造高效的小程序》(笔记1)WePY开发环境的安装

    WePY的安装或更新都通过npm进行,全局安装或更新WePY命令行工具,使用以下命令: npm install wepy-cli -g 稍等片刻,成功安装后,即可创建WePY项目. 注意:如果npm安 ...

  7. 浅谈HTML5的新特性

    2014年10月29日,W3C宣布,经过接近8年的艰苦努力,HTML5标准规范终于制定完成. HTML5将会取代1999年制定的HTML 4.01.XHTML 1.0标准,使网络标准达到符合当代的网络 ...

  8. 浅谈Python设计模式 -- 责任链模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 之前在最开始就聊了Python设计模式有三种,其中关于创建型和结构型设计模式基本 ...

  9. spark操作总结

    一.sparkContext与sparkSession区别 任何Spark程序都是SparkContext开始的,SparkContext的初始化需要一个SparkConf对象,SparkConf包含 ...

  10. PAT 乙级 1019.数字黑洞 C++/Java

    题目来源 给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字.一直重复这样做,我们很快会停在有 ...