问题描述

RMQ问题是求给定区间中的最值问题。对于长度为n的数列A,回答若干查询RMQ(A, i, j)。返回数组A中下标在[i,j]里的最小值的下标。
比如数列 5,8,1,3,6,4,9,5,7      那么RMQ(2,4) = 3, RMQ(6,9) = 6.
 
解决问题
最简单的解法时间复杂度是O(n),就是对于每一个查询遍历一遍数组。但是当n非常大的时候,并且查询次数非常多的时候,这个解决方案就不是那么高效了。
使用线段树(以后会讲)可以将时间复杂度优化到O(logn),通过在线段树中保存线段的最值。
不过本文将介绍一个解决RMQ最强大的算法,Sparse-Table算法。
Sparse-Table算法是一个在线算法,所 谓在线算法,是指用户每输入一个查询便马上处理一个查询。该算法一般用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询。 ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。

首 先是预处理,用动态规划(DP)解决。设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。例如数列3 2 4 5 6 8 1 2 9 7,F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。 F[1,2]=5,F[1,3]=8,F[2,0]=2,F[2,1]=4……从这里可以看出F[i,0]其实就等于A[i]。这样,DP的状态、初值都 已经有了,剩下的就是状态转移方程。我们把F[i,j]平均分成两段(因为f[i,j]一定是偶数个数字),从i到i+2^(j-1)-1为一 段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1))。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。F[i,j]就是这两段的最大值中的最大值。于是我们得到了动态规划方程F[i, j]=max(F[i,j-1], F[i + 2^(j-1),j-1])。

然 后是查询。取k=[log2(j-i+1)],则有:RMQ(A, i, j)=max{F[i,k],F[j-2^k+1,k]}。 举例说明,要求区间[2,8]的最大值,总共2到8是7个元素,所以k=2,那么就要把它分成[2,5]和[5,8]两个区间,因为这两个区间的最大值我 们可以直接由f[2,2]和f[5,2]得到。

具体如下图所示:

 
算法伪代码
//初始化
 
INIT_RMQ
 
//max[i][j]中存的是重i开始的2^j个数据中的最大值,最小值类似,num中存有数组的值
 
for i : 1 to n
 
  max[i][0] = num[i]
 
for j : 1 to log(n)
 
  for i : 1 to (n-2^j+1)
 
     max[i][j] = MAX(max[i][j-1], max[i+2^(j-1)][j-1])
 
//查询
 
RMQ(i, j)
 
k = log(j-i+1)
 
return MAX(max[i][k], max[j-2^k+1][k])
												

RMQ(Range Minimum Query)问题(转)的更多相关文章

  1. AOJ DSL_2_A Range Minimum Query (RMQ)

    Range Minimum Query (RMQ) Write a program which manipulates a sequence A = {a0,a1,...,an−1} with the ...

  2. Range Minimum Query and Lowest Common Ancestor

    作者:danielp 出处:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAnc ...

  3. RMQ (Range Minimal Query) 问题 ,稀疏表 ST

    RMQ ( 范围最小值查询 ) 问题是一种动态查询问题,它不需要修改元素,但要及时回答出数组 A 在区间 [l, r] 中最小的元素值. RMQ(Range Minimum/Maximum Query ...

  4. Geeks - Range Minimum Query RMQ范围最小值查询

    使用线段树预处理.能够使得查询RMQ时间效率在O(lgn). 线段树是记录某范围内的最小值. 标准的线段树应用. Geeks上仅仅有两道线段树的题目了.并且没有讲到pushUp和pushDown操作. ...

  5. RMQ((Range Minimum/Maximum Query))ST算法

    给定一个数组,求出给定区间[l,r]中元素的最大值或最小值或者最值的索引. 一看到这个题目,简单,看我暴力出奇迹.暴力当然是可行的.但是时间复杂度很高(O(n^2)).线段树,树状数组也可以解决这个问 ...

  6. Segment Tree Range Minimum Query.

    int rangeMinQuery(int segTree[], int qlow, int qhigh, int low, int high, int pos) { if (qlow <= l ...

  7. [LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  8. [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  9. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

随机推荐

  1. Couchbase第一印象(架构特性)

    Couchbase第一印象(架构特性) 面向文档 保存的字节流总有一个 DOCUMENT ID(Object_ID) 高并发性,高灵活性,高拓展性,容错性好 面向文档的集群存储系统 每个文档用一个唯一 ...

  2. struts2访问或添加几个属性(request/session/application属性)

    https://blog.csdn.net/hebiao100/article/details/7385055 struts2添加request.session.application属性 第一种方法 ...

  3. Leetcode 229.求众数II

    求众数II 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2,3] 输出: ...

  4. 【bzoj1055】[HAOI2008]玩具取名

    [bzoj1055][HAOI2008]玩具取名 2014年12月1日3,0111 Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名 ...

  5. 免费第三方API平台整合

    各大平台免费接口,非常适用 http://developer.51cto.com/art/201412/458778.htm 绝对干货:供个人开发者赚钱免费使用的一些好的API接口http://www ...

  6. mySQL windows 服务

    https://www.jizhuba.com/kejiyouxi/20171001/6006.html

  7. python学习之-- shutil模块

    shutil 模块功能:文件/文件夹的复制,压缩处理模块shutil.copyfileobj(fsrc,fdst[,length]):将文件内容拷贝到另一个文件中,也可以是部分内容举例:文件复制 im ...

  8. HDU 5665 Lucky

    看有没有0和1,都有的时候是YES,否则是NO #include<cstdio> #include<cstring> #include<cmath> #includ ...

  9. D. Spongebob and Squares--cf599D(数学)

    http://codeforces.com/problemset/problem/599/D 题目大意:给你一个数k  让你求一个n*m的矩形里面包含k个正方形   输出有几个这样的矩形  分别是什么 ...

  10. uva 662

    dp +路径输出 #include <cstdio> #include <cstdlib> #include <cmath> #include <stack& ...