ST 表
ST 表(Sparse Table,稀疏表)是一种用于高效解决可重复贡献问题的数据结构,主要用于静态区间查询(如区间最值、区间 GCD 等)。其核心思想是倍增预处理和动态规划,支持 预处理和 查询。
核心概念
- 可重复贡献问题:满足 且 的运算(如 , , )。
- 倍增思想:将区间拆分为两个重叠的子区间,通过预处理结果合并得到原区间答案。
实现原理
预处理()
- 状态定义:
表示区间 的最值(以最小值为例)。 - 状态转移:
- 将区间 拆分为 和 两部分。
- 初始化:
- 时,(区间长度为 1)。
查询()
查询区间 的最值:
- 计算 。
- 结果为:
- 两个子区间 和 覆盖 且可能有重叠(可重复贡献性保证正确性)。
核心代码
namespace st{
int stt[maxn][25];
inline void init(int n){
for(int i=1;i<=n;i++)stt[i][0] = a[i];
for(int j = 1;j <= __lg(n);j++)
for(int i=1;i+(1<<j)-1<=n;i++)
stt[i][j] = max(stt[i][j-1],stt[i+(1<<(j-1))][j-1]);
}
int find(int l,int r){
register int s = __lg(r-l+1);
return max(stt[l][s],stt[r-(1<<s)+1][s]);
}
}
例题
#include
#define int long long
using namespace std;
const int maxn = 1e5+5;
int n,m,l,r,a[maxn];
namespace st{
int stt[maxn][25];
inline void init(int n){
for(int i=1;i<=n;i++)stt[i][0] = a[i];
for(int j = 1;j <= __lg(n);j++)
for(int i=1;i+(1<<j)-1<=n;i++)
stt[i][j] = max(stt[i][j-1],stt[i+(1<<(j-1))][j-1]);
}
int find(int l,int r){
register int s = __lg(r-l+1);
return max(stt[l][s],stt[r-(1<<s)+1][s]);
}
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
st::init(n);
for (int i = 1; i <= m; i++) {
scanf("%d%d",&l,&r);
printf("%d\n",st::find(l,r));
}
return 0;
}