RMQ问题

原创 2016年05月31日 09:12:12

RMQ(Range Minimum/Maximum Query)问题是指对于长度为n的数列weight,回答若干询问RMQ(weight,l,r)(l,r<=n),返回数列A中下标在i,j里的最小(大)值。
假设询问m次,如果对于每个询问都扫描对应的区间,找到最值,那么最坏情况和平均情况下都是O(nm)的时间复杂度。所以需要事先进行一些预处理,使得一些重复计算的东西不再重复计算,才能够将复杂度降低下来。如果先预先计算一些区间的最值,然后把每个询问都拆成若干个计算了最值的区间并统计这些区间的最值的最值,就可以得出答案。根据二分法的思想,将统计的区间规定为所有长度为2的非负整数次幂的区间。用rmq[i][j]表示从第i个数开始后面2^j个数的最值,很显然rmq[i][0]等于weight[i],j的最大值为(int)((log(N))/(log(2.0)))。递推关系为rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1])。可以看到,这是一个动态规划问题。对于每一次询问,j的最大值mi只能取(int)((log(r-l+1))/(log(2.0)))。为了防止超出边界,答案应该写成min(rmq[l][mi],rmq[r-(1<<mi)+1][mi])而不是min(rmq[l][mi],rmq[l+(1<<mi)][mi])。
以hihoCoder1068为例给出代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>  
#include<algorithm>  
using namespace std;    
const int maxn=1e6+5;  
const int max_pos=20;  
struct Quary
{
	int l,r; 
}quary[maxn];   
int N,Q;  
int weight[maxn];  
int rmq[maxn][max_pos];   

int main()
{  
	scanf("%d",&N);  
    for(int i=1;i<=N;i++) scanf("%d",&weight[i]);  
    scanf("%d",&Q);
    for(int i=1;i<=Q;i++) scanf("%d%d",&quary[i].l,&quary[i].r);    
	memset(rmq,0x5f,sizeof(rmq)); 
  	for(int i=1;i<=N;i++) rmq[i][0]=weight[i];   
    int l=(int)((log(N))/(log(2.0)));  
    for(int j=1;j<=l;j++)
	{  
        for(int i=1;i+(1<<j)-1<=N;i++)
		{  
            rmq[i][j]=min(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);  
        }  
    } 
    for(int i=1;i<=Q;i++)
	{  
        int l=quary[i].l;  
        int r=quary[i].r;  
        int mi=(int)((log(r-l+1))/(log(2.0)));  
        printf("%d\n",min(rmq[l][mi],rmq[r-(1<<mi)+1][mi]));  
    }  
}


相关文章推荐

树的直径

在《算法导论》中有这样一个问题: 比如,下图中树的直径就是(6-4-2-1-3),长度为4。 有多种方法解决这个问题,我们讲解两种。 第一种办法是进行两次bfs搜索。假设s和t是直径上的两个端...

LCA问题

LCA(Least Common Ancestors)问题是指给定一棵树T和两个节点u和v,找出u和v的离根节点最远的公共祖先。 比如说对于下面这棵树,7和10的最近公共祖先是1,7和8的最近公共祖先...

RMQ与LCA问题

  • 2013年03月08日 16:31
  • 684KB
  • 下载

RMQ问题资料

  • 2014年02月18日 22:59
  • 141KB
  • 下载

hunnu11460(线段树解RMQ问题)

题意:求区间内每个数的因子个数的最大值,即区间求最值 一开始用ST算法写,超内存,然后就用线段树给搞定了 代码如下: #include #include #include #include #i...

LCA问题归约成RMQ求解

  • 2009年01月09日 16:10
  • 538KB
  • 下载

郭华阳《RMQ与LCA问题》

  • 2009年08月10日 10:16
  • 140KB
  • 下载

poj3264 rmq问题——st算法

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 27060   Accepted:...

ACM中的RMQ和LCA问题

  • 2011年01月16日 14:17
  • 239KB
  • 下载

RMQ问题之线段树(点修改)

上次的RMQ问题用了Sparse-Table算法来解决,然而就和之前那个最大连续和问题类似,如果要动态的修改数组的话,那么如果还用Sparse-Table算法的话,那么每次修改都要话O(nlogn)的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RMQ问题
举报原因:
原因补充:

(最多只允许输入30个字)