RMQ问题(超详细!!!)
一、简介
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问题(超详细!!!)的更多相关文章
- 【转】(超详细)jsp与servlet之间页面跳转及参数传递实例
初步学习JavaEE,对其中jsp与Servlet之间的传值没弄清楚,查看网上资料,发现一篇超详细的文章,收获大大,特此记录下来.具体链接:http://blog.csdn.net/ssy_shand ...
- 超强、超详细Redis数据库入门教程
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...
- Github上传代码菜鸟超详细教程【转】
最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- [转]超详细图解:自己架设NuGet服务器
本文转自:http://diaosbook.com/Post/2012/12/15/setup-private-nuget-server 超详细图解:自己架设NuGet服务器 汪宇杰 ...
- GitHub超详细图文攻略
GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git 分类: 转载2014-03-25 21:10 10641人阅读 评论(2) 收藏 举报 GitHubbr ...
- 超详细的Xcode代码格式化教程,可自定义样式。
超详细的Xcode代码格式化教程,可自定义样式. 为什么要格式化代码 当团队内有多人开发的时候,每个人写的代码格式都有自己的喜好,也可能会忙着写代码而忽略了格式的问题.在之前,我们可能会写完代码后,再 ...
- Struts2+Spring4+Hibernate4整合超详细教程
Struts2.Spring4.Hibernate4整合 超详细教程 Struts2.Spring4.Hibernate4整合实例-下载 项目目的: 整合使用最新版本的三大框架(即Struts2.Sp ...
- 超全超详细的HTTP状态码大全(推荐抓包工具HTTP Analyzer V6.5.3)
超全超详细的HTTP状态码大全 本部分余下的内容会详细地介绍 HTTP 1.1中的状态码.这些状态码被分为五大类: 100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. ...
- 安装64位Oracle 10g超详细教程
安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...
随机推荐
- .NET / C# EF中的基础操作(CRUD)
查 public List<users> Querys() { datatestEntities db = new datatestEntities(); var a = db.users ...
- 一张图看懂SharpBarcode
通过下面的图片,可以瞬间看懂整个SharpBarcode类库的脉络.
- HDFS文件浏览页返回上级目录功能
1.效果预览 Hadoop自带的效果 修改后,多了一个../按钮,点击可以回到上级目录 2.查找页面和JS文件 我们在浏览器上可以看到访问了explorer.html页面,可以尝试使用find命令查找 ...
- 一.B/S架构和C/S架构
1.B/S架构 Browser-Server, 浏览器和服务器架构.包含客户端浏览器.web应用服务器.数据库服务器的软件系统.用户只需要一个浏览器就可以访问服务.系统更新的时候,只需要更新服务端, ...
- 前端自动显示信息的小demo
效果: //来到这个页面立即请求,展示客户公司名称 $(function () { $.ajax({ type:"GET", url:"${pageContext.req ...
- drf--ModelSerializers序列化
目录 drf--ModelSerializers序列化 项目准备 配置 settings.py 路由 多表设计 表关系分析 创建models 模型序列化 自定义模型序列化 api/serializer ...
- 错误排查:Cloudera Manager Agent 的 Parcel 目录位于可用空间小于 10.0 吉字节 的文件系统上。 /opt/cloudera/parcels
临时解决办法: 点击右上角的抑制,选中抑制复选框,然后重启服务即可.
- Flask+SQLAlchemy+graphene+docker示例
搭建一个利用docker启动服务的Flask的小demo 定义数据库 # -*- coding: utf-8 -*- from sqlalchemy import * from sqlalchemy. ...
- H3C 802.11e 协议
- Odoo中的记录集
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826218.html 一:record set 1:获取记录集 1)在@api.multi修饰器修饰的函数 ...



