POJ3264 Balanced Lineup RMQ

直接维护好两个数组就可以了,每次访问得到区间的最小值和最大值。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int N, M, seq[50005], Min[50005][20], Max[50005][20];

void Minbuild()
{
    int LIM = (int)log2(double(N));
    for (int i = 1; i <= N; ++i) {
        Min[i][0] = seq[i]; 
    }
    for (int j = 1; j <= LIM; ++j) {
        for (int i = 1; i+(1<<j)-1 <= N; ++i) {
            Min[i][j] = min(Min[i][j-1], Min[i+(1<<j-1)][j-1]);
        }
    }
}

void Maxbuild()
{
    int LIM = (int)log2(double(N));
    for (int i = 1; i <= N; ++i) {
        Max[i][0] = seq[i];    
    }
    for (int j = 1; j <= LIM; ++j) {
        for (int i = 1; i+(1<<j)-1 <= N; ++i) {
            Max[i][j] = max(Max[i][j-1], Max[i+(1<<j-1)][j-1]);    
        }
    }
}

int Maxquery(int l, int r)
{
    int k = (int)log2(double(r-l+1));
    return max(Max[l][k], Max[r-(1<<k)+1][k]);
}

int Minquery(int l, int r)
{
    int k = (int)log2(double(r-l+1)); 
    return min(Min[l][k], Min[r-(1<<k)+1][k]);
}

int main()
{
    int l, r;
    while (scanf("%d %d", &N, &M) == 2) {
        for (int i = 1; i <= N; ++i) {
            scanf("%d", &seq[i]);    
        }
        Minbuild(), Maxbuild();
        for (int i = 1; i <= M; ++i) {
            scanf("%d %d", &l, &r); 
            printf("%d\n", Maxquery(l, r) - Minquery(l, r));
        }
    }
    return 0;    
}
原文地址:https://www.cnblogs.com/Lyush/p/2619115.html