RMQ问题模板

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define MAXN 10010
#define INF 1000000000
using namespace std;
int A[MAXN];
int N, M;
int Amax[MAXN][50];//Amax[i][j]表示从i开始的,长度为2的j次方的区间里面的最大值
int Amin[MAXN][50];//Amin[i][j]表示从i开始的,长度为2的j次方的区间里面的最小值
void RMQ_init()
{
    for(int i = 1; i <= N; i++)
        Amax[i][0] = Amin[i][0] = A[i];
    for(int j = 1; (1<<j) <= N; j++)
    {
        for(int i = 1; i + (1<<j)-1 <= N; i++)
        {
            Amax[i][j] = max(Amax[i][j-1], Amax[i+(1<<(j-1))][j-1]);
            Amin[i][j] = min(Amin[i][j-1], Amin[i+(1<<(j-1))][j-1]);
        }
    }
}
int query(char *op, int L, int R)
{
    //k值求法有两种
    int k = 0;
    while((1<<(k+1)) <= R-L+1) k++;
    //int k = (int)(log(double(R - L + 1))/log((double)2));
    if(strcmp(op, "MAX") == 0)
        return max(Amax[L][k], Amax[R-(1<<k)+1][k]);
    else
        return min(Amin[L][k], Amin[R-(1<<k)+1][k]);
}
int main()
{
    while(scanf("%d%d", &N, &M), N||M)
    {
        for(int i = 1; i <= N; i++)
            scanf("%d", &A[i]);
        RMQ_init();
        char op[10];
        int x, y;
        while(M--)
        {
            scanf("%s%d%d", op, &x, &y);
            printf("%d
", query(op, x, y));
        }
    }
    return 0;
}
 

优化版:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000000+10
using namespace std;
int N, M, k;
int A[MAXN];
int Amax[MAXN];
int Amin[MAXN];
void RMQ_init()
{
    for(int i = 1; i <= N; i++)
        Amax[i] = Amin[i] = A[i];
    for(int j = 1; (1<<j) <= k; j++)
    {
        for(int i = 1; i + (1<<j) - 1 <= N; i++)
        {
            Amax[i] = max(Amax[i], Amax[i + (1<<(j-1))]);//压缩
            Amin[i] = min(Amin[i], Amin[i + (1<<(j-1))]);
        }
    }
}
int query(char *op, int L, int R)
{
    int len = 0;
    while(1<<(len+1) <= R-L+1) len++;//求len值
    if(strcmp(op, "MAX") == 0)
        return max(Amax[L], Amax[R-(1<<len)+1]);
    else
        return min(Amin[L], Amin[R-(1<<len)+1]);
}
int main()
{
    while(scanf("%d%d%d", &N, &M, &k) != EOF)
    {
        for(int i = 1; i <= N; i++)
            scanf("%d", &A[i]);
        RMQ_init();
        char op[10];
        int x;
        while(M--)
        {
            scanf("%s%d", op, &x);
            printf("%d
", query(op, x, x+k-1));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tp25959/p/10427655.html