【学习笔记】Sparse Table算法

版权声明:欢迎转载评论 https://blog.csdn.net/m0_37809890/article/details/82585410

RMQ问题

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干次询问RMQ(i,j),返回数列A中下标在区间[i,j]中的最小/大值。

ST算法

ST(Sparse Table,稀疏表,ST表)是用来解决RMQ问题的一种算法,预处理复杂度O(nlogn),查询复杂度O(1),不支持在线查询

构造

ST表的构造采用了动态规划的思想,
状态表示: s t [ i ] [ j ] = m a x k = j j + 2 i 1 a [ k ] ,即从j到j+2^i-1的最大(或最小)值。
初始状态: s t [ 0 ] [ j ] = a [ j ]
状态转移: s t [ i ] [ j ] = m a x ( s t [ i 1 ] [ j ] , s t [ i 1 ] [ j + 2 i 1 ] )
i 1 l o g n j 1 n ,一共 O ( n l o g n ) 个状态,每次转移复杂度 O ( 1 ) ,总构造复杂度 O ( n l o g n )

查询

我们已经知道以任意一点开始了长度为2的幂次的区间最大值,如果要求长度为L的[x,y]区间内的最大值,就可以求[x,x+k],[y-k+1,y]这两个区间最大值的最大值,其中k是小于L的最大2的幂次。
m a x ( s t [ t ] [ x ] , s t [ t ] [ y 2 t + 1 ] ) t = l o g 2 ( y x + 1 )
log函数可以预处理一个数组,每次查询复杂度 O ( 1 )

代码

学习了一些C++类的知识,静态成员必须在类外定义及初始化,在类中只是声明,且在类外用双冒号表示这是一个类的静态成员。
因为不会写模板类,所以额外用了一个变量表示求最大还是最小,0表示求最小值,1表示求最大值。如果哪位巨巨有更好的方法请教教我。
另外,vector初始化第一个参数表示大小,第二个表示初始值,所以二维vector的初始化方式:vector<vector<int>> vvi(outsize, vector<int>(insize))

class SpraseTable
{
    static vector<int> Log;
    static void init()
    {
        Log[0] = -1;
        for(int i = 1; i < M; i++)
            Log[i] = Log[i / 2] + 1;
    }
    int n, type, t;
    vector<vector<int>> table;
    inline int fun(int a, int b)
    {
        return (a < b)^type ? a : b;
    }
public:
    SpraseTable(vector<int> &src, int _type) : n(src.size() - 1), type(_type)
    {
        if(!Log[0]) init();
        table = vector<vector<int>>(Log[n] + 1, vector<int>(n + 1));
        for(int i = 1; i <= n; i++)
            table[0][i] = src[i];
        for(int i = 1; i <= Log[n]; i++)
            for(int j = 1; j <= n; j++)
                if(j + (1 << i) - 1 <= n)
                    table[i][j] = fun(table[i-1][j], table[i-1][j+(1<<(i-1))]);
    }
    inline int query(int x, int y)
    {
        t = Log[y - x + 1];
        return fun(table[t][x], table[t][y - (1 << t) + 1]);
    }
};vector<int> SpraseTable::Log(M);

其他

ST表蕴含了倍增的思想,下次再细学。
ST表维护的运算需要满足什么性质?首先肯定是半群上的,然后为什么这种做法不能用来求区间和?

猜你喜欢

转载自blog.csdn.net/m0_37809890/article/details/82585410