poj3264(Sparse-Table 算法模板)

poj3264

题意

询问区间最大值最小值之差。

分析

dp_max[i][j] 表示以 i 为起点,长度为 (2^j) 的区间最大值。
利用递推预处理出区间最大值最小值。

code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN = 1e5 + 10;
int n, dp_max[MAXN][20], dp_min[MAXN][20];
void init() {
    for(int i = 1; (1 << i) < MAXN; i++) {
        for(int j = 1; j <= n; j++) {
            dp_max[j][i] = max(dp_max[j][i - 1], dp_max[j + (1 << (i - 1))][i - 1]);
            dp_min[j][i] = min(dp_min[j][i - 1], dp_min[j + (1 << (i - 1))][i - 1]);
        }
    }
}
int query(int l, int r) {
    int k = (int)(log((double)r - l + 1) / log(2.0));
    return max(dp_max[l][k], dp_max[r - (1 << k) + 1][k])
         - min(dp_min[l][k], dp_min[r - (1 << k) + 1][k]);
}
int main() {
    int q;
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &dp_max[i][0]);
        dp_min[i][0] = dp_max[i][0];
    }
    init();
    while(q--) {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d
", query(l, r));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/7192182.html