poj_3264 Balanced Lineup 用ST算法解RMQ问题

DP的思想:从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1)),状态转移方程为: 

           F[i,j]=max(F[i,j-1],F[i+2^(j-i),j-1])
最大值 f[i,j]=max(f[i,j-1],f[i+2^(j-1),j-1]);
 最小值 f[i,j]=min(f[i,j-1],f[i+2^(j-1),j-1]);
View Code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
const int N = 50001;
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
int h[N],maxx[N][16],minx[N][16];
int n,m;
void Init()
{
    for(int i=1;i<=n;i++) maxx[i][0]=minx[i][0]=h[i];
    int k=floor(log((double)n)/log(2.0));
    for(int i=1;i<=k;i++)
        for(int j=n;j>=1;j--)
        {
            int jj=j+(1<<(i-1));
            maxx[j][i]=maxx[j][i-1];
            minx[j][i]=minx[j][i-1];
            if(jj<=n)
            {
                maxx[j][i]=Max(maxx[j][i-1],maxx[jj][i-1]);
                minx[j][i]=Min(minx[j][i-1],minx[jj][i-1]);
            }
        }
}
int rmq(int l,int r)
{
    int k=floor(log((double)(r-l+1))/log(2.0));
    int mx=Max(maxx[l][k],maxx[r-(1<<k)+1][k]);
    int mi=Min(minx[l][k],minx[r-(1<<k)+1][k]);
    return mx-mi;
}
int main()
{
    int l,r;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);
        Init();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&l,&r);
            printf("%d\n",rmq(l,r));
        }
    }
    return 0;
}

 

posted @ 2012-07-06 21:02  lenohoo  阅读(194)  评论(0)    收藏  举报