注意
間違い、改善点等を見つけたら教えてもらえると助かります。(直すとは言ってない)
はじめに
先にこっちを見て
beet-aizu.hatenablog.com
問題はここから持ってきました。
https://onlinejudge.u-aizu.ac.jp/#/courses/library/3/DSL/2
はじめに
セグ木ってなに?の人はとりあえず↓
https://www.slideshare.net/iwiwi/ss-3578491
遅延伝播セグメント木についてはこちら↓
beet-aizu.hatenablog.com
「セグ木とは、前計算と最小限の更新で、区間に対する操作を受け止めることができるデータ構造のこと」
である(と僕は思っている)。
また、セグ木には様々な種類があるが、このブログでは大まかに5つに分けて、
A: 一点更新区間取得:うし木
B: 区間更新一点取得(更新が可換):らて木
C: 区間更新一点取得(上の制限なし):びーと木 双対セグ木
D: 区間更新区間取得(更新が可換):Starry Sky木
E: 区間更新区間取得(上の制限なし):遅延セグ木
と呼ぶことにする。(長いので)
簡単のため、添え字は0-indexedとし、区間は の半開区間を用い、要素は 個であることとする。
(要素が 個ではなかったとしても、末尾に適当な値を入れておくことで 個にできるので)
うし木
まずは一番簡単なうし木から始める。
うし木を書くときに要求される条件は、要素がモノイド(あるいは半群)であることだけだ。
半群やモノイドはあまり聞きなれない言葉かもしれないが、
ある集合 に対して(例えば とか とか)に対して、二項演算 が与えられて、
結合律
が成り立つ時 を半群といい、半群 に関して、
ある が存在して、任意の について
が成り立つとき、 を を単位元とするモノイドという。
参考:
https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8E%E3%82%A4%E3%83%89
日常的な例でいうと、
は半群だが、単位元が存在しないためモノイドではない。
は0を単位元とするモノイドである(したがって半群でもある)。
また、 は1を単位元とするモノイドである。
半群からモノイドを生成
ここは別に飛ばしてもいい。
任意の半群について、ある元 を に追加して を作り、
任意の について と定義すると、
は を単位元とするモノイドとなる。
言い換えると、適当な単位元を追加することによって、任意の半群をモノイドに埋め込むことができる。
先ほどの例を思い返すと、 はモノイドではなかったが、
とすることで、モノイドに埋め込むことができる。
これは絶対に必要なテクニックというわけではないが、覚えておくと実装をサボれることがある。
モノイドの例
ここまで無限集合ばかり例に挙げてきたが、
いくつか有限集合の例も挙げておく。
現実の問題では、 や などがよく出てくる。
モノイドのメリット
更新、取得の両方の操作が で行えることを示していく。
説明の都合上、まずは取得について考える。
という区間は、前計算で求めた区間を高々 個使って表せる。
例えば なら
なら
なら
のようになる。
うまい説明を思いつかないので証明は省略する。
さて、前置きが長くなってしまったが、
区間 を 個の区間 に分解し、
に対して演算を行なった結果と定義すると、
と表すことができて、下の式の の数は高々 個であり、
の中身は前計算であらかじめ求めてあるため、全体として で演算できる。
ここで上の式から下の式に変形する際に、結合法則を繰り返し用いている。
つまり、 がモノイドであることが、このように区間に分けて操作を行うための必要十分条件である。
次に、更新が で行えることを示す。
に対して変更を行ったときに影響のある区間は 個である。
よって、愚直に再計算し直すだけでよい。
例えば、下の図は を変更を行った場合の更新が必要な要素を表している。
結論として、モノイドのメリットとは
ことだと言えるだろう。
具体例
イメージしやすいように、具体的な問題を取り上げる。
https://onlinejudge.u-aizu.ac.jp/#/courses/library/3/DSL/2/DSL_2_A
これは一番基本的なうし木の問題であると言える。
制約から、 であり、
を満たしているから、 は半群である。
また、 とすると、 は を単位元とするモノイドでもある。
したがって、この問題はセグ木を使って解くことができる。
実装例:
https://onlinejudge.u-aizu.ac.jp/#/solutions/problem/DSL_2_A/review/2594507/beet/C++11
クソ長くなったので一回切りまつ。
次回は様々なセグ木の関係性についてまとめようと思っています。