预处理区间最值O(nlogn)
查询O(1)
对于一组长度为N的队列,进行M次询问,每次询问一个区间,查找该区间内的最大数值
如果用暴力枚举的话,时间复杂度最坏能到O(NNM),当数据量大时肯定会TLE
ST表是一种预处理复杂度为O(logn),查询复杂度为O(1)的一种查区间最值的方法,但是这种方法有缺陷,仅限于数据元素不变的静态表,当数据元素会实时发生变化时并不适用(用线段树解决动态区间最值问题,蒻苟还没学线段树,不会这个)
ST表,预处理二维数组 st [ i ][ j ],其中表示数组中第 i 位置开始 2^j 个位置内的最值,所以对于int类型,j的范围就在30以下,该预处理二维数组的大小还是挺小的。
有点类似倍增,我们发现 st [ 3 ][ 2 ] 可以将2分成两个1,就是把22分成了21的两个部分,用 max ( st [ 3 ][ 1 ],st [ 5 ][ 1 ] ) 两个部分来表示 st [ 3 ][ 2 ] 的区间最大值。
查询的时候先计算出查询区间的长度(我们需要找到一个最大的k满足2^k<=len),因为不能保证区间长度是2的次方,所以我们需要在区间内找到一个x值,使得 x + 2^k -1= r,因此
x=r-2^k+1 ,我们只需要查询 max ( st [ l ][ m ] ,st [ r - ( 1<<m ) + 1 ][ m ] ))即可
1 |
|
当然,也可以用ST表查询最小值,静态区间最值问题都可以解决,要抓紧时间学学线段树了,马上就大二了。。。
附上洛谷 题目:
P3865 【模板】ST 表 - 洛谷 | 计算机科学教育新生态