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系统的连 ...
随机推荐
- 使用HttpClient访问接口(Rest接口和普通接口)
这里总结一下使用HttpClient访问外部接口的用法.后期如果发现有什么缺陷会更改.欢迎读者指出此方法的不足之处. 首先,创建一个返回实体: public class HttpResult { // ...
- mybatis中用注解如何处理存储过程返回的多个结果集?
sql代码: create procedure sptest.getnamesanditems() reads sql data dynamic result sets 2 BEGIN ATOMIC ...
- C# MemcacheHelper封装
using Memcached.ClientLibrary; using System; using System.Collections.Generic; using System.Linq; us ...
- Java 11 新特性介绍
Java 11 已于 2018 年 9 月 25 日正式发布,之前在Java 10 新特性介绍中介绍过,为了加快的版本迭代.跟进社区反馈,Java 的版本发布周期调整为每六个月一次——即每半年发布一个 ...
- GitHub Vue项目推荐|Vue+Element实现的电商后台管理系统功能丰富
GitHub Vue项目推荐|mall-admin-web是一个电商后台管理系统的前端项目基于Vue+Element实现 主要包括商品管理.订单管理.会员管理.促销管理.运营管理.内容管理.统计报表. ...
- OpenSessionInViewFilter 的配置及替代方案
OpenSessionInViewFilter 的配置及替代方案 博客分类: hibernate OpenSessionInViewFilter 的配置及替代方案 Spring 为我们提供了一个叫做 ...
- tensorflow 镜像
https://mirrors.tuna.tsinghua.edu.cn/tensorflow/windows/cpu/ 报错 不支持 C:\Users\brady\.conda\envs\tenso ...
- Linux开发环境配置大全
Linux开发环境配置 零章:通过xshell在linux上安装JDK8 壹章:通过xshell在linux上安装tomcat8 贰章:通过xshell在linux上安装mysql5.7(终极版) 叁 ...
- main process exited, code=exited, status=203/EXEC
问题描述: Oct :: c_3. systemd[]: Started etcd. Oct :: c_3. systemd[]: Starting etcd... Oct :: c_3. syste ...
- Odoo Controller详解
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826241.html 一:Controller 一般通过继承的形式来创建controller类,继承自od ...