RMQ问题

RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题 。

解决这类问题常用的是tarjan的Sparse_table算法,即稀疏表算法。
它的预处理时间是O( nlogn ),但是查询时间为O( 1 )
Balanced Lineup

#include <cstdio>
#include<algorithm>
#include <stdlib.h>
#include<string.h>
#define maxn 50005
using namespace std;
int dmin[maxn][16],dmax[maxn][16];
int rmq_min(int l,int r)
{
    int k=0;
    while((1<<(k+1))<=r-l+1) k++;//如果2^(k+1)<=r - l + 1,那么k还可以加1
    //可以保证2^k最大等于区间长度,那么范围查询不越界,且左右半边至少无空隙
    return min(dmin[l][k],dmin[r-(1<<k)+1][k]);
}
int rmq_max(int l,int r)
{
    int k=0;
    while((1<<(k+1))<=r-l+1) k++;
    return max(dmax[l][k],dmax[r-(1<<k)+1][k]);
}
int main()
{
    int n,m,a,b;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a);
        dmin[i][0]=a;
        dmax[i][0]=a;
    }
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=0;i+(1<<j)-1<n;i++)
        {
            dmin[i][j]=min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]);
            dmax[i][j]=max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
        }
    }
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        printf("%d\n",rmq_max(a-1,b-1)-rmq_min(a-1,b-1));
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,353评论 0 33
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 5,947评论 0 2
  • 小羚阅读 760评论 0 4
  • 我们只是万千世界飘零的一片, 因为风的抬爱,我们相遇, 沙儿见证了我们的相识。 风停了,我们散了, 飘零了很久,路...
    如冰1阅读 1,742评论 0 1
  • 高中生活已经开始一个月了,今天是我十五岁生日。我的爸妈一直都在外地为生活而奔波,小的时候总是一直跟随着父母在外...
    傻不傻啊阅读 4,026评论 0 0