Sparse Table
Sparse Table
ST表
定义
ST表(稀疏表)是一种基于倍增思想,用于解决可重复贡献问题的数据结构。
ST表应用最广泛的领域便是解决RMQ问题(Range Minimum/Maximum Query):给定n个数,m个询问,对于每个询问,需要回答区间[ l , r ] 中的最大值或最小值(可以采用两个数组同时进行处理)。
基于倍增的思想,ST表可以实现O(nlogn)下进行预处理,并在O(1) 时间内回答每个询问。如果仅仅进行区间最值查询,ST表的效率完全吊打线段树;但是,相比于线段树,ST表并不支持修改操作,无论是单点修改还是区间修改都不支持。
什么是可重复贡献问题
可重复贡献问题是对于运算o p t ,运算的性质满足x o p t x = x ,则对应的区间询问就是一个可重复的贡献问题,例如:最大值满足m a x ( x , x ) = x ,最大公因数满足g c d ( x , x ) = x ,因此RMQ问题和GCD问题就是一个可重复贡献的问题,但是例如区间和就不满足这个性质,因为在求解区间和的过程中采用的预处理区间会发生重叠,导致重叠部分被重复计算,因此对于o p t 操作还需要满足集合率才能够使用ST表进行求解。
重点:求[l,r]区间的最大值或最小值是可重复贡献问题,而求和不是可重复贡献问题。
ST表的原理和实现
我们发现,区间最大值是一个具有“可重复贡献”性质的问题。即使用来求解的预处理区间有重叠部分,只要这些区间的并是所求的区间,最终计算出的答案就是正确的。
以最大值为例,设f [ i ] [ j ] 表示整个数列A中下标在子区间[ i , i + $2{^j}$ − 1 ] 里的数的最大值,也就是从i开始的$2{^j}$ 个数的最大值。递推边界显然是f [ i ] [ 0 ] = A [ i ] ,即数列A在区间[ i , i ]里的最大值。
初始化
在递推时,我们把子区间的长度成倍增加,于是我们就能轻轻松松得到下面的这个递推表达式:
f[i][j]=max(f[i][j−1],f[i+$2^{j−1}$][j−1])
1 | void Initial() { |
查询
查询区间最大值
1 | int query_Max(int l, int r) { |
查询区间最小值
1 | int query_Min(int l, int r) { |
ST表的其他应用
除 RMQ 以外,还有其它的“可重复贡献问题”。例如“区间按位和”、“区间按位或”、“区间 GCD”,ST 表都能高效地解决。
需要注意的是,对于“区间 GCD”,ST 表的查询复杂度并没有比线段树更优(令值域为 w,ST 表的查询复杂度为 Θ ( log w ) ,而线段树为 Θ ( log n + log w ) ,且值域一般是大于 n 的),但是 ST 表的预处理复杂度也没有比线段树更劣,而编程复杂度方面 ST 表比线段树简单很多。
如果分析一下,“可重复贡献问题”一般都带有某种类似 RMQ 的成分。例如“区间按位与”就是每一位取最小值,而“区间 GCD”则是每一个质因数的指数取最小值。
模板题
这是之前用树状数组AC过的模板题,主要适用于ST表,所以在这放一下别人ST表的AC代码。
Balanced Lineup G
[USACO07JAN] Balanced Lineup G
题目描述
每天,农夫 John 的 $n(1\le n\le 5\times 10^4)$ 头牛总是按同一序列排队。
有一天, John 决定让一些牛们玩一场飞盘比赛。他准备找一群在队列中位置连续的牛来进行比赛。但是为了避免水平悬殊,牛的身高不应该相差太大。John 准备了 $q(1\le q\le 1.8\times10^5)$ 个可能的牛的选择和所有牛的身高 $h_i(1\le h_i\le 10^6,1\le i\le n)$。他想知道每一组里面最高和最低的牛的身高差。
输入格式
第一行两个数 $n,q$。
接下来 $n$ 行,每行一个数 $h_i$。
再接下来 $q$ 行,每行两个整数 $a$ 和 $b$,表示询问第 $a$ 头牛到第 $b$ 头牛里的最高和最低的牛的身高差。
输出格式
输出共 $q$ 行,对于每一组询问,输出每一组中最高和最低的牛的身高差。
样例 #1
1 | 6 3 |
样例输出 #1
1 | 6 |
AC代码
改了一下码风,原来的码风太丑了。
1 |
|
- Title: Sparse Table
- Author: Charles
- Created at : 2023-01-07 16:55:34
- Updated at : 2023-07-30 10:52:49
- Link: https://charles2530.github.io/2023/01/07/sparse-table/
- License: This work is licensed under CC BY-NC-SA 4.0.