【RMQ】POJ 3264

开两个dp数组分别记录最大值和最小值就ok。

#define N 50010
int max(int a,int b){return a>b?a:b;}
int dp1[20][N];
int dp2[20][N];
int f[N];
int n,m;
void init_rmq(){
    int i,j;
    for(i=1;i<=n;i++){
        dp1[0][i] = f[i];
        dp2[0][i] = f[i];
    }
    int t = floor(log((double)n)/log(2.0));//向下取整
    for(i=1;i<=t;i++){
        for(j=1;j+(1<<(i-1))<=n;j++){
            dp1[i][j] = max(dp1[i-1][j],dp1[i-1][j+(1<<(i-1))]);
            dp2[i][j] = min(dp2[i-1][j],dp2[i-1][j+(1<<(i-1))]);
        }
    }
}

int rmq(int i,int j){
    int k = floor(log((j-i+1)*1.0)/log(2.0));
    int minm = MAX,maxm = 0;
    maxm = max(dp1[k][i],dp1[k][j-(1<<k)+1]);
    minm = min(dp2[k][i],dp2[k][j-(1<<k)+1]);
    return maxm - minm;
}

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




















你可能感兴趣的:(【RMQ】POJ 3264)