RMQ可以用来查找区间最值(最大或最小)
二维RMQ可以用来求子矩阵的最值问题。
RMQ先将所有起点的向后跳2^i的数最值求出来,然后查询的时候再查找两个区间
dp[i][j]表示i~i+2^j-1这2^j个数中的最值,如果用区间表示的话,就是
[i,i+2^j)
这样的话我们可以得到一个公式
dp[i][j]=max(dp[i][j-1],dp[i+(1<<j)][j-1];
i~2^j-1可以分成求两个区间的最值[i,i+2^j)--> max [i,i+2^(j-1)) [i+2^(j-1),i+2^j)
区间的最值是可以合并的。
一维数组使用RMQ的话时间复杂度是
O(n*log(n))-O(1)
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define MAXN 200010
const int N_N=log2(MAXN)+2;
int n,k;
int d[MAXN][N_N];
int a[MAXN];
inline int max(int a, int b) {
return a > b ? a : b;
}
void st() {
int m, i, j;
for(int i=1;i<=n;i++)
d[i][0]=a[i];
//m = (int) (log((double) n) / log(2.0));
m=log2(n);
for (j = 1; j <= m; ++j) {
for (i = 1; i + (1 << j) - 1 <= n; ++i)
d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
}
}
int