documentation_of |
---|
//structure/segment-tree/segment-tree.hpp |
完全二分木である. モノイドについて区間に対する演算が
モノイドは次の条件を満たす代数的構造である.
- 結合律を満たす. つまり
$S$ の各元$a, b, c$ に対して,$(a \cdot b) \cdot c = a \cdot (b \cdot c)$ が満たされる. - 単位元をもつ. つまり
$S$ の任意の元$a$ をとってきたときに$a \cdot e = e \cdot a = a$ なる$e$ が存在する.
実装では木を 1-indexed の配列で表現している. ノード
計算量のオーダーを表記していない関数は全て
-
SegmentTree(n, f, M1)
: サイズn
で初期化する. ここでf
は2つの区間の要素をマージする二項演算,M1
はモノイドの単位元である.$O(n)$ -
SegmentTree(v, f, M1)
: 配列v
で初期化する.f
とM1
は上と同様.$O(n)$ -
build(v)
: 配列v
で初期化する.$O(n)$ -
set(k, x)
:k
番目の要素をx
に変更する. -
get(k)
:k
番目の要素を返す.$O(1)$ -
operator[k]
:k
番目の要素を返す.$O(1)$ -
apply(k, x)
:k
番目の要素をその要素とx
を二項演算した値に変更する. -
prod(l, r)
: 区間$[l, r)$ に対して二項演算した結果を返す. -
all_prod()
: 全体を二項演算した結果を返す.$O(1)$ -
find_first(a, check)
:$[a, x)$ がcheck
を満たす最初の要素位置$x$ を返す. 存在しないとき$n$ を返す.$O(\log n)$ -
find_last(b, check)
:$[x, b)$ がcheck
を満たす最後の要素位置$x$ を返す. 存在しないとき$-1$ を返す.$(\log n)$
auto seg = get_segment_tree(N, f, M1);
のようにすると decltype(f)
を用いなくてすむ.