ST表效率比线段树高, 可以查询区间最值, 但不能实时更新
mi[i][j]代表从i开始, 往后2^j个元素的最小值, 也就是区间[i, i+2^j-1]的最小值
预处理时利用mi[i][j-1] 和 mi[i+(1<<(j-1))][j-1]更新mi[i][j]
查询是也是通过两段相互重合的比要查询区间小一点的区间得到最小值
复杂度预处理
O(nlogn)
, 查询
O(logn)
, 差不多是
O(1)
int mi[maxn][30];
void init_rmq(int a[], int n)
{
for (int i = 0; i < n; ++i) mi[i][0] = a[i];
for (int j = 1; (1 << j) <= n; ++j)
{
for (int i = 0; i + (1 << j) <= n; ++i)
{
mi[i][j] = min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
}
}
}
int rmq(int l, int r)
{
int k = 0;
while ((1 << (k + 1)) <= r - l + 1) ++k;
return min(mi[l][k], mi[r - (1 << k) + 1][k]);
}