SparseTable ST表

Sparse Table

ST表是一个静态二维数组st[i][j],作用是快速查询(O(1))区间最值(不只是最值,可重复贡献问题都可以用),st[i][j]代表的是在以引索i为起点,长度为(2^j)的区间内最值,缺点是只能静态查询,不支持修改。

实现

建表

对于要查询的数组a[n],首先创建一个二维数组st[i][j],(0le i<n, ; 0le jle log_{(n)}). 解释一下j的值域,j代表查询区间的大小((2^j)),所以,如果我们要查询区间a[0,n)的最值,那么就是st[0][j],其中(j=lceil log_2n ceil).

填表

这里用的是动态规划的方法,复杂度为(nlog n)。一个长度为(2^j)区间的最值就等于这个区间前(2^{j-1})个元素的最值和后(2^{j-1})个元素的最值中的最值。所以状态转移方程为(st[i][j] = max(st[i][j-1], st[i+2^{j-1}, j-1])).

for(int i=0; i<n; ++i) 
    st[i][0] = a[i]; //长度为2^0=1的区间就是a[i]本身

for(int j=1; j<=ceil(log(n)/log(2)); ++j)
    for(int i=0; i<n; ++i) {
        if(i+(1<<j) > n+1) break;  //区间越界
        st[i][j] = max(st[i][j-1], st[i+(1<<(j-1))][j-1]);
    }

查询

因为ST表只能的查询区间长度都为2的幂次((2^j)),那么我们要查询的区间长度不是2的幂次怎么办.

任意一个正整数都可以拆分成若干个2的幂次的和。例如我们查询区间[3,10)区间长度为7,7可以拆分为1+2+4,那么我们要查询的最值就是max(st[3][0], st[4][1], st[6][2]).

原文地址:https://www.cnblogs.com/rookiezjz/p/12771901.html