[模板] ST表

学了这么久还不会 ST 表,药丸

ST 表是一种用来求解 RMQ 问题的 O(log n) 算法,相比于线段树求解 RMQ 问题要更简洁,码量小,常数也更小,是一种基于倍增思想的算法。

我们定义数组 f[i][j] 表示第 i 个元素到 第 i+2j 个元素区间范围内极值,那么可以根据倍增思想轻松写出转移方程。

f[i][j]=f[i][j1]+f[i+(1<<(j1))+1][j1]

查询请求也非常简单,我们将区间 [l,r] 拆为长度为 log2(rl+1) 的两部分,最后合并答案即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int MAXN = 100000 + 10;
const int MAXK = 17 + 10;

int f[MAXN][MAXK];
int data[MAXN];
int n;

inline void ST_init(){
    for(register int i=1; i<=n; i++)
        f[i][0] = data[i];

    int maxj = log(n) / log(2) + 1;

    for(register int j=1; j<maxj; j++){
        for(register int i=1; i<= n - (1 << j) + 1; i++)
            f[i][j] = max(f[i][j-1], f[i+ (1 << (j - 1))][j-1]);
    }
}

inline int query(int l, int r){
    int j = log(r-l+1) / log(2);    
    return max(f[l][j], f[r - (1 << j) + 1][j]);
}
C++