POJ 3264 Balanced Lineup (RMQ)

查询区间最大的数减最小的数

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f
#define maxnn 50005
int a[maxnn];
int maxn[maxnn][20];
int minn[maxnn][20];
int pos[maxnn];

void initRMQ(int n)
{
    pos[0]=-1;
    for(int i=1; i<=n; i++)
    {
        pos[i]=((i&i-1)==0)?(pos[i-1]+1):pos[i-1]; //求logi 避免精度误差
        minn[i][0]=maxn[i][0]=a[i];
    }
    for(int j=1; j<=pos[n]; j++)
    {
        for(int i=1; i+(1<<j)-1<=n; i++)
        {
            maxn[i][j]=max(maxn[i][j-1],maxn[i+(1<<(j-1))][j-1]);
            minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
        }
    }
}

int rmq(int l,int r)
{
    int k=pos[r-l+1];
    return max(maxn[l][k],maxn[r-(1<<k)+1][k])-min(minn[l][k],minn[r-(1<<k)+1][k]);
}

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }
        initRMQ(n);
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d\n",rmq(a,b));
        }
    }
    return 0;
}


你可能感兴趣的:(RMQ)