ST表 学习笔记
ST 表(Sparse Table,稀疏表)是用于解决可重复贡献问题的数据结构。典型的应用是可以 \(O(\log n)-O(1)\) 解决 RMQ 问题(区间的最值查询,Range Maximum/Minimum Query)。
ST 表运用了倍增的思想。以静态区间最大值为例,设 \(f_{i,j}\) 表示第 \(i\) 个数及以后 \(2^j\) 个数的最大值。有 \(f_{i,0}=a_i,f_{i,j}=\max(f_{i,j-1},f_{i+2^{j-1},j-1})\)。
查询区间 \([l,r]\),设 \(k=\lfloor\log_2(r-l+1)\rfloor\),可以用两个区间 \([l,l+2^s-1],[r-2^s+1]\) 完全覆盖这个区间,答案为 \(\max(f_{l,s},f_{r-2^s+1,s})\)。
可以预处理以 \(2\) 为底的对数,有 \(\lfloor\log_2i\rfloor=\lfloor\log_2\lfloor\frac{i}{2}\rfloor\rfloor+1,\lfloor\log_21\rfloor=0\)。
代码:
template<typename T,int maxn1,int maxn2>struct ST{
T st[maxn1][maxn2];
int lg[maxn1];
void build(int n,T a[]){
for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++)st[i][0]=a[i];
for(int j=1;1<<j<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
T query(int l,int r){
return max(st[l][lg[r-l+1]],st[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
}
};
ST 表查询的过程中,两个区间不一定没有交集,这说明 ST 表只能解决可重复贡献问题。也就是说查询的运算 \(\operatorname{opt}\) 满足 \(a\operatorname{opt}a=a\)。比如按位与,按位或,GCD 等。这个运算也应满足结合律。
比如一道题:P1890
区间 gcd 满足可重复贡献问题,把上面的 max 换成 gcd 即可。
[[数据结构]]

浙公网安备 33010602011771号