poj 3264 RMQ 最小值 最大值

ST算法(Sparse Table):它是一种动态规划的方法。
以最小值为例。a为所寻找的数组.
用一个二维数组f(i,j)记录区间[i,i+2^j-1](持续2^j个)区间中的最小值。其中f[i,0] = a[i];
所以,对于任意的一组(i,j),f(i,j) = min{f(i,j-1),f(i+2^(j-1),j-1)}来使用动态规划计算出来。
这个算法的高明之处不是在于这个动态规划的建立,而是它的查询:它的查询效率是O(1).
假设我们要求区间[m,n]中a的最小值,找到一个数k使得2^k<n-m+1.
这样,可以把这个区间分成两个部分:[m,m+2^k-1]和[n-2^k+1,n].我们发现,这两个区间是已经初始化好的.
前面的区间是f(m,k),后面的区间是f(n-2^k+1,k).

这样,只要看这两个区间的最小值,就可以知道整个区间的最小值!

poj 3264

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define M 50005
int mx[M][16],mi[M][16];
int a[M];

void rmqinit(int n)
{
    for(int i=1;i<=n;i++)
    {
        mx[i][0]=mi[i][0]=a[i];
    }
    int i,j;
    for(j=1;1<<j<=n;j++)  //here:Why j is in front of i ??
    {
        for(i=1;i+(1<<j)-1<=n;i++)
        {
            int t=(1<<(j-1))+i;
            mx[i][j]=max(mx[i][j-1],mx[t][j-1]);
            mi[i][j]=min(mi[i][j-1],mi[t][j-1]);
        }
    }
}

int qmx(int l,int r)
{
    int k=(int)( log((r-l+1)*1.0) / log(2.0));
    return max(mx[l][k],mx[r-(1<<k)+1][k]);
}

int qmi(int l,int r)
{
    int k=(int)( log((r-l+1)*1.0) / log(2.0));
    return min(mi[l][k],mi[r-(1<<k)+1][k]);
}

int main()
{
    int n,q,l,r;
    while(~scanf("%d%d",&n,&q))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",a+i);
        }
        rmqinit(n);

        while(q--)
        {
            scanf("%d%d",&l,&r);
            printf("%d\n",qmx(l,r)-qmi(l,r));
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值