概要
長さ の数列 に対する区間 add と区間 min を時間計算量 で処理する、空間計算量 のデータ構造を説明する。 ただし、一連の操作における の最大値を としたとき、 の範囲の数を管理するために必要な空間計算量を としている。
例: 長さ の数列に の加算クエリが 回ほど行われる状況では、 bit 整数 個のメモリで処理できる。
構造
簡略化のため、 が の冪の場合をまず考える。 Segment Tree と同様に、配列を用いて二分木の構造を作る。 まず、各ノードに対して対応する区間内の最小値を考える (この値は実際には保持しない)。 続いて、各ノードに対して左子 右子を計算し、これを保持する。 葉には子が無いので、データは保持しない。 すると下図のような構造となる。
この右側のデータに加えて全体の最小値も持つことで、Segment Tree に対するものと似たようにクエリの処理が可能となる。 例えば区間 add では、データを適切に更新しつつ、着目しているノードの区間の最小値の増分を返すような関数を設計すると良い。 区間 に を加算するクエリは以下のようになる
- 着目しているノードの区間が に完全に含まれているなら、 を返す。
- 着目しているノードの区間が と交差しないなら、 を返す。
- 左子と右子に対して再帰的に加算クエリを行う。それぞれの返り値から着目しているノードの値を更新し、返り値を計算する。
が の冪でない場合も、空間計算量が の Segment Tree と同様に完全二分木でない二分木構造を作ればよい。 ノードの個数は になるため、全体の最小値の管理と併せて 個の整数を管理することになる。