摘自网友,具体哪个忘记了,抱歉~

定义:

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算法】的更多相关文章

  1. poj 3264 区间最大最小值 RMQ问题之Sparse_Table算法

    Balanced Lineup Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java ...

  2. ST(RMQ)算法(在线)求LCA

    在此之前,我写过另一篇博客,是倍增(在线)求LCA.有兴趣的同学可以去看一看.概念以及各种暴力就不在这里说了,那篇博客已经有介绍了. 不会ST算法的同学点这里 ST(RMQ)算法在线求LCA 这个算法 ...

  3. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  4. 求解区间最值 - RMQ - ST 算法介绍

    解析 ST 算法是 RMQ(Range Minimum/Maximum Query)中一个很经典的算法,它天生用来求得一个区间的最值,但却不能维护最值,也就是说,过程中不能改变区间中的某个元素的值.O ...

  5. [POJ3264]Balanced Lineup(RMQ, ST算法)

    题目链接:http://poj.org/problem?id=3264 典型RMQ,这道题被我鞭尸了三遍也是醉了…这回用新学的st算法. st算法本身是一个区间dp,利用的性质就是相邻两个区间的最值的 ...

  6. 【原创】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算法作 ...

  7. HDU 3183 - A Magic Lamp - [RMQ][ST算法]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3183 Problem DescriptionKiki likes traveling. One day ...

  8. LCA上的RMQ模板算法

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. POJ 3264 Balanced Lineup RMQ ST算法

    题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...

随机推荐

  1. Spring学习九 Servlet相关

    servlet作用: 它驻留在 Web 服务器上,处理新来的请求和输出的响应.它与表示无关,实际上也不它应该与表示有关. 作为一名专业编程人员,您碰到的大多数 Java servlet 都是为响应 W ...

  2. 如何在C#中读写INI文件

    INI文件就是扩展名为"ini"的文件.在Windows系统中,INI文件是很多,最重要的就是"System.ini"."System32.ini&q ...

  3. c++ 端口扫描程序

    第一.原理 端口扫描的原理很简单,就是建立socket通信,切换不通端口,通过connect函数,如果成功则代表端口开发者,否则端口关闭. 所有需要多socket程序熟悉,本内容是在window环境下 ...

  4. 在云服务器上体验Docker

    1. 添加Docker repository key sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -" 2. ...

  5. #调整随机森林的参数(调整n_estimators随机森林中树的数量默认10个树,精度递增显著,但并不是越多越好),加上verbose=True,显示进程使用信息

    #调整随机森林的参数(调整n_estimators随机森林中树的数量默认10个树,精度递增显著) from sklearn import datasets X, y = datasets.make_c ...

  6. 回调函数(callback)经典解答

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:常溪玲链接:http://www.zhihu.com/question/19801131/answer/13005983来源: ...

  7. __tostring和__invoke 方法

    首先放上代码: <?php class MagicTest{ //__tostring会在把对象转换为string的时候自动调用 public function __tostring() { r ...

  8. nginx 代理参数介绍

    2)我们可以看到nginx文件夹内有一个conf文件夹,其中有好几个文件,其他先不管,我们打开nginx.conf,可以看到一段: 这段代码在server里面,相当于一个代理服务器,当然可以配置多个. ...

  9. Spring第五天

    1. [简答题]:简述一下hibernate和spring框架的整合步骤: 答: 1.加入hibernate jar包 2.编写持久化类 3.添加Hibernate的配置文件:hibernate.cf ...

  10. tomcat启动时加载配置文件 报错

    原因:  @serice("customerService")  和@Repository(value="customerDao")       解决: 直接@ ...