对于ST表研究
ST表概论
ST表是一个基于倍增思想的算法。不支持任何形式的修改,支持区间查询。
其中,维护的信息需要满足结合律和幂等律。
-
结合律:对于一个操作 \(\text{opt}(\alpha,\beta)\),有 \(\text{opt}(x,\text{opt}(y,z)) = \text{opt}(\text{opt}(x,y),z)\)。
-
幂等律:对于一个操作 \(\text{opt}(\alpha,\beta)\),有 \(\text{opt}(x,x)=x\)。
显然,以下操作支持ST表:
- 最值,\(\max\) 和 \(\min\)。
- \(\gcd\) 与 \(\text{lcm}\)。
- 按位 \(\text{and},\text{or}\)
思想
以下以区间 \(\max\) 举例,其他操作类似。
令 \(f[i][j]=\max\{ i \to i+2^{j}-1\}\)
显然有 \(f[i][0]=a_i\)。
初始化
递推式为:\(f[i][j]=f[i][j-1]+f[i+2^{j-1}][j-1]\)。
查询
对于查询 \([l,r]\),令 \(k=[\log_{2}(r-l+1)]\)
\(\max\{l \to r\} = \max\{ f[l][l+2^s-1], f[r-2^s+1][r]\}\)。
复杂度
预处理时间复杂度为 \(O(n\log n)\)。
查询时间复杂度 \(O(1)\)。
优势与劣势
优:代码简单,不难背诵,效率高。
劣:不支持修改,需要幂等律。
模板
P3865 【模板】ST 表
求区间最大值。
#include
#include
using namespace std;
int STTable[1000005][25];
int max(int x, int y){
if(x>y){
return x;
}
else{
return y;
}
}
inline int read() {
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') {
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9') {
x=x*10+ch-48;
ch=getchar();
}
return x*f;
}
int query(int l,int r) {
int k=log2(r-l+1);
return max(STTable[l][k],STTable[r-(1<