ST表,适用于解决RMQ(区间最值问题),类似于线段树和树状数组这两个算法
ST表相比于线段树,预处理的复杂度与线段树一样,而查询的复杂度则大大快于线段树
| 预处理 | 查询 | |
| ST表 | O(nlogn) | O(1) |
| 线段树 | O(nlogn) | O(logn) |
ST表:
线段树(不开O2):
线段树(开O2优化):
经比较,我们可以轻而易举的看出,当我们解决RMQ问题时,ST表的速度明显优于线段树
ST表的主体是一个二维数组:st[i][j]。表示查询的数组的下标i到i+2^j-1
如何进行预处理呢??
首先,我们把从0~n-1的2^0的部分进行覆盖
然后向下处理
Q:处理??怎么处理??
A:不明白??那我们来举一个例子
我们以一个长度为5的数组
2^0部分覆盖过去就是 a[1],a[2],a[3],a[4],a[5]
2^1部分的长度为4,也就是下标从1到4,
st[0][1]是下标为0~1的区间的最值
也就是st[0][0]和st[0][1]的最值
以此往下类推
结论:st[i][j] = min ( st[i][j-1] , st[i + 2^(j-1) ][j-1] );
预处理函数(求最大值):
inline void init(int n) { 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]); } } }