【数据结构】ST表

验证链接:https://www.luogu.com.cn/problem/P3865

struct SparseTable {

    static const int MAXN = 200000 + 10;
    static const int MAXLOGN = 20;

    int n;
    int log2[MAXN];
    int mi[MAXN][MAXLOGN];
    int mx[MAXN][MAXLOGN];

    void Init(int *a, int _n) {
        n = _n;
        for(int i = 2; i <= n; ++i)
            log2[i] = log2[i >> 1] + 1;
        for(int i = 1; i <= n; ++i) {
            mi[i][0] = a[i];
            mx[i][0] = a[i];
        }
        for(int j = 1; j <= log2[n]; ++j) {
            for(int i = 1; i + (1 << j) - 1 <= n; ++i) {
                mi[i][j] = min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
                mx[i][j] = max(mx[i][j - 1], mx[i + (1 << (j - 1))][j - 1]);
            }
        }
    }

    int Min(int l, int r) {
        l = max(l, 1);
        r = min(r, n);
        if(l > r)
            return INF;
        int s = log2[r - l + 1];
        return min(mi[l][s], mi[r - (1 << s) + 1][s]);
    }

    int Max(int l, int r) {
        l = max(l, 1);
        r = min(r, n);
        if(l > r)
            return -INF;
        int s = log2[r - l + 1];
        return max(mx[l][s], mx[r - (1 << s) + 1][s]);
    }

} st;

这个模板处理了访问区间越界以及访问区间为空的情况。扩大MAXN的时候注意检查MAXLOGN是否满足要求,当MAXN<=1e6的情况都不需要修改MAXLOGN。

LOG2可能可以用builtin函数来计算,具体可以看看这个博客

和这个文章 https://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Other-Builtins.html#Other-Builtins

GCC的内建函数 __lg(x)返回的是 \(\lfloor \log_2 x \rfloor\)准确值 所以可以直接用这个代替上文的 log2[x]

注:常用log2表

i=16  (1<<i)=65536
i=17  (1<<i)=131072
i=18  (1<<i)=262144
i=19  (1<<i)=524288
i=20  (1<<i)=1048576
posted @ 2021-01-21 10:33  purinliang  阅读(107)  评论(0)    收藏  举报