RMQ静态区间最值查询

来源:互联网 发布:农村淘宝面试题目 编辑:程序博客网 时间:2024/06/05 04:47
//RMQ algorithm:O(nlogn)预处理,O(1)查询. 适合静态数组处理区间最值问题,使用了动态规划的思想
//对于静态数组来说,前缀和及后缀和可以解决区间和查询的问题,而RMQ可以解决区间最值查询的问题
//对于需要动态更新的数组来说,需要使用线段树来维护,线段树预处理O(n),查询O(logn)
#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1000+5;
vector<int> a;
int d[maxn][maxn];
int n;
//构建RMQ
void RMQ_init()
{
       for(int i=0;i<n;i++) d[i][0]=a[i];                   /*写法与dp雷同*/
       for(int j=1;(1<<j)<=n;j++)
           for(int i=0;i+(1<<j)-1<n;i++)
                d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
//查询
int RMQ(int l,int r)
{
    int k=0;
    while((1<<(k+1))<=r-l+1) k++;
    return min(d[l][k],d[r-(1<<k)+1][k]);
}
int main()
{
    while(scanf("%d",&n)==1&&n)
    {
        for(int i=0;i<n;i++)
        {
            int m;
            scanf("%d",&m);
            a.push_back(m);
        }
        RMQ_init();
        int l,r;
        while(scanf("%d%d",&l,&r)==2)
        {
            if(l>=r||r>n-1||l<0) {
                    printf("Input is wrong.\n");                    //输入非法
                    break;
            }
            cout<<RMQ(l,r)<<endl;
        }
        a.clear();
        memset(d,0,sizeof(d));
    }
    return 0;
}

原创粉丝点击