RMQ-ST算法的理解与实现(C++)
RMQ-ST的含义

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。ST算法(Sparse Table),ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法(在线算法指用户每输入一个查询便马上处理一个查询),它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。
预处理
设a[i]表示需要求区间最值的数列,f[i][j]表死从第i个数起连续2^j个数中的最大值。
则很容易得到状态转移方程:f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1])
实现代码:
void rmq(int n) //n为a序列的长度
{
for(int j=;j<=;j++) //注意是外层循环j嵌套内层i循环
for(int i=;i<=n;i++)
if(i+(<<(j-))-<=n)
{
smin[i][j]=min(smin[i][j-],smin[i+(<<(j-))][j-]); //更新最小值
smax[i][j]=max(smax[i][j-],smax[i+(<<(j-))][j-]);//更新最大值
}
}
先更新所有长度为f[i][0]即1个元素,然后通过2个1个元素的最值获得所有长度为f[i][1](即两个元素的最值),再到3个、4个……依次类推更新
查询
若查询的区间为[i][j],因为该区间的长度为j-i+1,所以可以取k=log2(j-i+1),假设所求的为最大值则易得maxn=max(f[i][k],f[j-(2^k)+1][k]);
不妨举个例子假设a[13]={5,1,8,1,6,4,2,9,7,4,1,13,3},假设需要查询的是i=7到j=13这个区间,log2(13-7+1)=2,则可以知所求区间最大值=max(f[7][2],f[13-(22)+1][2])=13,
可以看出f[7][2]表示的是7到10这4个位置的最大值,而f[13-(22)+1][2]表示的是10到13这4个位置的最大值,两者的最大值即7到13这个区间的最大值,很神奇吧!!!聪明的读者一定会注意到,f[i][k]和f[j-(2^k)+1][k]会有交集,但聪明的你又会马上明白就算有交集也并不会影响最值(反而如果没有交集,便不能保证最值的准确性),自己思考一下吧!
int k=log2(l-r+);//(int)((log(l-r+1))/log(2.0));
int q=max(smax[r][k],smax[l-(<<k)+][k]),w=min(smin[r][k],smin[l-(<<k)+][k]);
模板题
地址 https://www.luogu.org/problem/show?pid=1816
标准的rmq-st模板题,可以去尝试做一下
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int a[][],m,n;
inline int getint() //读入优化
{
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')f=,x=getchar();
while(x>=''&&x<='')
{a=a*+x-'';x=getchar();}
return f?-a:a;
}
void rmq_st(int n) //预处理,st表
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++) //思考为什么外循环j套i,而不是外循环i套j
if(i+(<<j)-<=n)
a[i][j]=min(a[i][j-],a[i+(<<(j-))][j-]); //原因在于每个区间更新都是由1个点开始慢慢增加区间范围
}
int main()
{
m=getint();n=getint();
for(int i=;i<=m;i++)a[i][]=getint(); //读入数据,对于每个点开始时最小值就是它本身
rmq_st(m);
while(n--)
{
int l=getint(),r=getint(),k=log2(r-l+);
printf("%d ",min(a[l][k],a[r-(<<k)+][k])); //查询时注意思路
}
return ;
}
RMQ-ST算法的理解与实现(C++)的更多相关文章
- 【原创】RMQ - ST算法详解
ST算法: ID数组下标: 1 2 3 4 5 6 7 8 9 ID数组元素: 5 7 3 1 4 8 2 9 8 1.ST算法作 ...
- POJ 3264 Balanced Lineup RMQ ST算法
题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...
- 求解区间最值 - RMQ - ST 算法介绍
解析 ST 算法是 RMQ(Range Minimum/Maximum Query)中一个很经典的算法,它天生用来求得一个区间的最值,但却不能维护最值,也就是说,过程中不能改变区间中的某个元素的值.O ...
- [POJ3264]Balanced Lineup(RMQ, ST算法)
题目链接:http://poj.org/problem?id=3264 典型RMQ,这道题被我鞭尸了三遍也是醉了…这回用新学的st算法. st算法本身是一个区间dp,利用的性质就是相邻两个区间的最值的 ...
- HDU 3183 - A Magic Lamp - [RMQ][ST算法]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 Problem DescriptionKiki likes traveling. One day ...
- 关于基础RMQ——ST算法
RMQ,Range Maximum/Minimum Query,顾名思义,就是询问某个区间内的最大值或最小值,今天我主要记录的是其求解方法--ST算法 相对于线段树,它的运行速度会快很多,可以做到O( ...
- POJ 3368 Frequent values RMQ ST算法/线段树
Frequent values Time Limit: 2000MS Memory Lim ...
- RMQ st算法 区间最值模板
#include<bits/stdc++.h> ; ; int f[N][Logn],a[N],lg[N],n,m; int main(){ cin>>n>>m; ...
- RMQ问题(线段树+ST算法)
转载自:http://kmplayer.iteye.com/blog/575725 RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ ...
- RMQ问题(线段树算法,ST算法优化)
RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值 ...
随机推荐
- 通俗语言解释内外网IP与端口映射
IP:分为外网IP和内网IP 也就是我们说的外网IP属于实体IP 实体IP,它是独一无二的,在网络的世界里,每一部计算机的都有他的位置,一个 IP 就好似一个门牌!例如,你要去百度的网站的话,就要去『 ...
- Java的常用操作符
操作符用于接受一个或多个参数,并生成一个新的值.加号和一元的正号(+).减号和一元的负号(一).乘号(*).除号(/)以及赋值号(=)的用法和大多数编程语言都类似. 操作符作用于操作数,生成一个新值. ...
- Oracle03——游标、异常、存储过程、存储函数、触发器和Java代码访问Oracle对象
作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7476717.html 1.游标(光标)Cursor 在写java程序中有集合的概念,那么 ...
- js中bind、call、apply函数的用法 (转载)
最近看了一篇不错的有关js的文章,转载过来收藏先!!! 最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web 的项目,然后在腾讯实习的时候用 j ...
- Mysql 分区详解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt120 一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.m ...
- sublime text3 3143 注册码
sublime text3 3143 注册码,可用~ Sublime Text一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制.相比于难于上手的Vi ...
- 想做iPhoneX抢购活动?压测大师先教你优化网站后台
北京时间9月13日凌晨1点,iPhone 10周年,在Apple Park乔布斯剧院,苹果发布了三款新iPhone.全面屏iPhone X来袭,这款被定义为未来的智能手机黑科技满满:全面屏,无线充电. ...
- 改造百度ueditor字体为rem及相关体会
提到富文本,可能大家都用到过百度的ueditor,作为一个重量级的插件,总结起来一句话,功能很强大,使用很费心.不知道是不是太久没有维护了,ueditor的文档可读性还真是差也可能是悟性不够吧.本文也 ...
- 转:【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17348313 happen-before规则介绍 Java语言中有一个"先行发生 ...
- 定时任务之crontab命令
1.简介 crontab用于设置周期性被执行的命令 Linux系统中Linux调动工作分为两大类: 1.系统执行的工作:系统周期性所要执行的工作,如备份系统数据.清理缓存 2.个人执行的工作:某个用户 ...