ST算法

ST算法:基于倍增原理的算法,一般用于静态的区间最值查询问题(RMQ)。

  对数列的每一个元素,我们将它分成单独的区间,将其作为第一组,再对每两个元素分成单独的区间,作为第二组,再对四个元素分成单独区间,依次类推。我们可以看到,如果多个小区间完全覆盖一个大区间(可以重叠但不超过),则大区间的最值一定和这些小区间的最值相等。
  该算法和树形数据结构相当,子节点将自己的最值依次向上传给父节点,在对区间查询时,不需要和线段树一样一层层搜寻,我们只需要找到两个小区间进行拼凑就行,所以查询的时间复杂的仅为 O(1)。
  在计算每组区间的最值时,我们采用动态规划(后续的组的值可以由前面的组得来且无后续性),定义dp[ s ][ k ], s为区间的左端点,k为区间内元素个数,k的值每次倍增,也就是k<<1,所以如果我们想要上一组的最值,那么应该以当前组的左端点开始,往右k-1格,再将左端点加上2^(k-1)得到另一个左端点,因为是倍增,所以加上1<<(k-1),得到状态转移方程:
    dp[ s ][ k ] = min { dp[ s ][ k -1 ],dp[ s+1<<( k-1 ) ][ k-1 ] }

在for循环中注意数组不要越界。


 对区间进行查询时,定义需要查询的区间为[ L , R ],所以区间的长度为R-L+1,我们用两个小区间完全覆盖,所以小区间的长度至少是查询区间长度的一半,而小区间长度全都是2正数幂,设小区间长度为2^k, k=log2(R-L+1),向下取整。第一个小区间的左端点为查询区间的端点,长度为k,第二个小区间的左端点为查询区间的右端点减去k加1,长度为k。所以查询区间的最值就是这两个区间的最值,即:
   ans = min { dp[ L ][ k ],dp[ R- ( 1 << k ) + 1 ][ k ] }

posted @ 2024-11-27 21:36  _窗帘  阅读(44)  评论(0)    收藏  举报