【RMQ】【Sparse_Table算法】
摘自网友,具体哪个忘记了,抱歉~
定义:
RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:
对于长度为n的数列A,回答若干询问RMQ(A,i,j) (i,j<=n),返回数列A中下标在i,j之间的最小/大值。
此类问题的解决方法有很多,暴力(当然也就说说,基本没有出题的会让你暴过去)、线段树(复杂度为O(nlogn))、以及一个非常有名的在线处理RMQ问题的算法 -- Sparse_Table算法,简称ST算法,该算法能在进行O(nlogn)的预处理后达到查询O(1)的效率。主要思想为dp。
(一)预处理,DP
设A[i]是要求区间最值的数列,dp[i][j]表示从第i个数起连续2j个数中的最大值。
例如有A[10] = 3 2 4 5 6 8 1 2 9 7;
初值:
dp[1][0]表示第1个数起,长度为20=1的最大值,即元素3。同理 dp[1][1] = max(3,2) = 3, dp[1][2]=max(3,2,4,5) = 5,dp[1][3] = max(3,2,4,5,6,8,1,2) = 8;
并且我们可以容易的看出dp[i][0] = A[i]。
状态转移方程:
我们把dp[i][j]分成长度相同且为2j-1的两段,一段为dp[i][2j - 1], 一段为dp[i+2j - 1][2j - 1]。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。
dp[i,j]就是这两段各自最大值中的最大值。于是我们得到了状态转移方程:
dp[i][j] = max(dp[i][j-1], dp[i + 2(j-1)][j-1];
/*预处理->O(nlogn)*/
int dp[maxn][];
void initRMQ(int n)
{
for(int i = ; i <= n; i++) dp[i][] = A[i];
for(int j = ; j <= ; j++)
for(int i = ; i + ( << (j-)) <= n; i++)
dp[i][j] = max(dp[i][j-], dp[i+(<<(j-))][j-]);
}
注意代码中循环的顺序,外层是j,内层是i!!
(二)查询
若查询区间为A[i, j],那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可重叠,比如查询A[5,9],我们可以查询A[5678]和A[6789])。
因为这个区间的长度len = j - i + 1,所以我们可以取k=log2(len),则有:RMQ(A, i, j) = max{ dp[i][k], dp[j-2k+1][k] }。
例如,查询区间[2,8]的最大值,k = log2(8 - 2 + 1) = 2,即求max( dp[2][2],dp[8 - 2 ^ 2 + 1][2]) = max(F[2, 2],F[5, 2]);
int Log2[maxn];
void init()
{
Log2[] = -; Log2[] = ;
int i, j;
for(i = , j = ; i < maxn; i++)
{
if(i > (<<(j+))) j++;
Log2[i] = j;
}
} int query(int L, int R)
{
if(L > R) swap(L, R);
if(L == R) return dp[L][];
int len = R-L+;
int k = Log2[len]; //此处用的是Log2[]数组保存每个数的log值,当然也可以用下面的式子求得;
//int k = (int)(log(R - L + 1.0) / log(2.0));
return max(dp[L][k], dp[R-(<<k)+][k]);
}
RMQ常常应用在字符串问题里.
【RMQ】【Sparse_Table算法】的更多相关文章
- poj 3264 区间最大最小值 RMQ问题之Sparse_Table算法
Balanced Lineup Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java ...
- ST(RMQ)算法(在线)求LCA
在此之前,我写过另一篇博客,是倍增(在线)求LCA.有兴趣的同学可以去看一看.概念以及各种暴力就不在这里说了,那篇博客已经有介绍了. 不会ST算法的同学点这里 ST(RMQ)算法在线求LCA 这个算法 ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- 求解区间最值 - RMQ - ST 算法介绍
解析 ST 算法是 RMQ(Range Minimum/Maximum Query)中一个很经典的算法,它天生用来求得一个区间的最值,但却不能维护最值,也就是说,过程中不能改变区间中的某个元素的值.O ...
- [POJ3264]Balanced Lineup(RMQ, ST算法)
题目链接:http://poj.org/problem?id=3264 典型RMQ,这道题被我鞭尸了三遍也是醉了…这回用新学的st算法. st算法本身是一个区间dp,利用的性质就是相邻两个区间的最值的 ...
- 【原创】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算法作 ...
- HDU 3183 - A Magic Lamp - [RMQ][ST算法]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 Problem DescriptionKiki likes traveling. One day ...
- LCA上的RMQ模板算法
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- POJ 3264 Balanced Lineup RMQ ST算法
题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...
随机推荐
- RPCServiceClient-调用webservice客户端
import javax.xml.namespace.QName; import org.apache.axis2.AxisFault; import org.apache.axis2.address ...
- js正则基础总结和工作中常用验证规则
知识是需要系统的.就像js正则用了那么多次,却还是浑浑噩噩,迫切需要来一次整理,那么来吧! 基本知识 元字符 \d 匹配数字等于[0-9] \w 匹配字母.数字.下划线.中文 \s 匹配任意空白字符 ...
- DAY5-模块与包
一.模块的介绍 1.什么是模块 #常见的场景:一个模块就是一个包含了一组功能的python文件,比如spam.py,模块名为spam,可以通过import spam使用. #在python中,模块的使 ...
- solr笔记--solr3.2以后支持document和json两种对象来更新索引
1.json形式(比如把mongodb数据库的导出结果json) <requestHandler name="/update" class="solr.JsonUp ...
- linux鸟哥的私房菜
这书还是感觉非常棒,真的是授之以渔而不是授之以鱼.我觉得只需要掌握一个命令就可以了man -k KEYWORD 比如我想查找和防火墙相关的命令,那么 man -k firewall 结果是ufw 然后 ...
- Java-马士兵设计模式学习笔记-工厂模式-模拟Spring读取Properties文件
一.目标:读取properties文件,获得类名来生成对象 二.类 1.Movable.java public interface Movable { void run(); } 2.Car.java ...
- 前端基础 之JS
浏览目录 JavaScript语法基础 JavaScript数据类型及类型查询 JavaScript运算符 JavaScript流程控制 JavaScript函数 词法分析 JavaScript内置对 ...
- 创建Mat对象
Mat 是一个非常优秀的图像类,它同时也是一个通用的矩阵类,可以用来创建和操作多维矩阵.有多种方法创建一个 Mat 对象. 1.构造函数方法 下面是一个使用构造函数创建对象的例子. 常用的构造函数 2 ...
- web.xml中url-pattern匹配规则.RP
一.url-pattern的三种写法 精确匹配.以"/"开头,加上servlet名称. /ad 路径匹配.以"/"开头,加上通配符"*" ...
- 使用python进行数据转码
大数据最烦的就是数据质量差,为了把数据导入到sequoiadb中,需要要求文本是UTF-8模式的,使用enca查看文件编码是gb2312,然后是enca转utf-8报错.google了整个地球都不知道 ...