cpplib

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub morioprog/cpplib

:heavy_check_mark: Sparse Table
(datastructure/sparsetable.hpp)

概要

静的な数列に対する区間取得クエリを定数時間で答えられるデータ構造.

渡す二項演算$f$は結合律と冪等律を満たす必要がある.

計算量

使用例

Verified with

Code

/**
* @brief Sparse Table
* @docs docs/datastructure/sparsetable.md
*/

template <typename T>
struct SparseTable {
    vector<vector<T>> st;
    using F = function<T(T, T)>;
    const F f;
    SparseTable() {}
    SparseTable(const vector<T> &v, const F f)
        : f(f) {
        int b = 0, sz = v.size();
        while ((1 << b) <= sz) ++b;
        st.assign(b, vector<T>(1 << b));
        for (int i = 0; i < sz; ++i) st[0][i] = v[i];
        for (int i = 1; i < b; ++i) {
            for (int j = 0; j + (1 << i) <= (1 << b); ++j) {
                st[i][j] = f(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
            }
        }
    }
    T query(const int l, const int r) const {
        int b = 31 - __builtin_clz(r - l);
        return f(st[b][l], st[b][r - (1 << b)]);
    }
};
#line 1 "datastructure/sparsetable.hpp"
/**
* @brief Sparse Table
* @docs docs/datastructure/sparsetable.md
*/

template <typename T>
struct SparseTable {
    vector<vector<T>> st;
    using F = function<T(T, T)>;
    const F f;
    SparseTable() {}
    SparseTable(const vector<T> &v, const F f)
        : f(f) {
        int b = 0, sz = v.size();
        while ((1 << b) <= sz) ++b;
        st.assign(b, vector<T>(1 << b));
        for (int i = 0; i < sz; ++i) st[0][i] = v[i];
        for (int i = 1; i < b; ++i) {
            for (int j = 0; j + (1 << i) <= (1 << b); ++j) {
                st[i][j] = f(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
            }
        }
    }
    T query(const int l, const int r) const {
        int b = 31 - __builtin_clz(r - l);
        return f(st[b][l], st[b][r - (1 << b)]);
    }
};
Back to top page