This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub maspypy/library
#include "ds/sparse_table/xor_disjoint_sparse_table.hpp"
template <typename Monoid> struct Xor_Disjoint_Sparse_Table { using MX = Monoid; using X = typename Monoid::value_type; int log; vvc<X> dat; Xor_Disjoint_Sparse_Table() {} Xor_Disjoint_Sparse_Table(int n) { build(n); } template <typename F> Xor_Disjoint_Sparse_Table(int n, F f) { build(n, f); } Xor_Disjoint_Sparse_Table(const vc<X>& v) { build(v); } void build(int m) { build(m, [](int i) -> X { return MX::unit(); }); } void build(const vc<X>& v) { build(len(v), [&](int i) -> X { return v[i]; }); } template <typename F> void build(int m, F f) { log = 0; while ((1 << log) < m) ++log; assert(m == (1 << log)); // 各 k, i に対して、prod_{0<=j<2^k} A[i^j] を持つ dat.resize(log + 1); dat[0].reserve(1 << log); FOR(i, 1 << log) dat[0].eb(f(i)); FOR(k, log) { dat[k + 1].assign(1 << log, MX::unit()); FOR(i, 1 << log) { dat[k + 1][i] = MX::op(dat[k][i], dat[k][i ^ (1 << k)]); } } } // calculate prod_{l<=i<r} A[x xor i], in O(log N) time. X prod(int l, int r, int xor_val) { X xl = MX::unit(), xr = MX::unit(); FOR(k, log + 1) { if (l >= r) break; if (l & 1 << k) { xl = MX::op(xl, dat[k][l ^ xor_val]); l += (1 << k); } if (r & 1 << k) { r -= (1 << k); xr = MX::op(dat[k][r ^ xor_val], xr); } } return MX::op(xl, xr); } };
#line 1 "ds/sparse_table/xor_disjoint_sparse_table.hpp" template <typename Monoid> struct Xor_Disjoint_Sparse_Table { using MX = Monoid; using X = typename Monoid::value_type; int log; vvc<X> dat; Xor_Disjoint_Sparse_Table() {} Xor_Disjoint_Sparse_Table(int n) { build(n); } template <typename F> Xor_Disjoint_Sparse_Table(int n, F f) { build(n, f); } Xor_Disjoint_Sparse_Table(const vc<X>& v) { build(v); } void build(int m) { build(m, [](int i) -> X { return MX::unit(); }); } void build(const vc<X>& v) { build(len(v), [&](int i) -> X { return v[i]; }); } template <typename F> void build(int m, F f) { log = 0; while ((1 << log) < m) ++log; assert(m == (1 << log)); // 各 k, i に対して、prod_{0<=j<2^k} A[i^j] を持つ dat.resize(log + 1); dat[0].reserve(1 << log); FOR(i, 1 << log) dat[0].eb(f(i)); FOR(k, log) { dat[k + 1].assign(1 << log, MX::unit()); FOR(i, 1 << log) { dat[k + 1][i] = MX::op(dat[k][i], dat[k][i ^ (1 << k)]); } } } // calculate prod_{l<=i<r} A[x xor i], in O(log N) time. X prod(int l, int r, int xor_val) { X xl = MX::unit(), xr = MX::unit(); FOR(k, log + 1) { if (l >= r) break; if (l & 1 << k) { xl = MX::op(xl, dat[k][l ^ xor_val]); l += (1 << k); } if (r & 1 << k) { r -= (1 << k); xr = MX::op(dat[k][r ^ xor_val], xr); } } return MX::op(xl, xr); } };