RMQ问题

作者: Gitfan | 来源:发表于2017-03-15 21:41 被阅读0次

    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));
        }
    }
    

    相关文章

      网友评论

          本文标题:RMQ问题

          本文链接:https://www.haomeiwen.com/subject/peprnttx.html