差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン次のリビジョン両方とも次のリビジョン | ||
programming_algorithm:data_structure:binary_indexed_tree [2020/02/26] – [累積和の二分探索] ikatakos | programming_algorithm:data_structure:binary_indexed_tree [2020/06/04] – [概要] ikatakos | ||
---|---|---|---|
行 5: | 行 5: | ||
[[http:// | [[http:// | ||
- | Range Sum Query(区間の和)に対する効率的なデータ構造 | + | Range Sum Query(区間の和)に対する効率的なデータ構造。 |
- | * 数列$a_1, | + | * 数列 $a_1, |
* 以下の2つの要求を処理する | * 以下の2つの要求を処理する | ||
- | * aiaiにxxを加算($1 \le i \le n$) | + | * aiai に xx を加算($1 \le i \le N$) |
- | * $a_sからa_t$までの合計を得る($1 \le s \le t \le n$) | + | * $a_s~a_tの合計を得る(1 \le s \le t \le N$) |
Binary Indexed Treeは、この2つを高速に行える。 | Binary Indexed Treeは、この2つを高速に行える。 | ||
行 49: | 行 49: | ||
</ | </ | ||
- | 注意点として、配列のindex等と異なり、添え字は1から始まる。そうしないと効率的に上下の要素を特定できないため。 | + | 注意点として、配列のindex等と異なり、添え字は1から始まる。その方が効率的に上下の要素を特定できるため。 |
⇤←←←←←←8 | ⇤←←←←←←8 | ||
行 55: | 行 55: | ||
⇤2 | ⇤2 | ||
1 3 5 7 9 ... | 1 3 5 7 9 ... | ||
+ | |||
+ | 添え字を2進数にしたもの。 | ||
+ | |||
+ | ⇤─←─←─←─←─←─←─1000 | ||
+ | ⇤─←─←─0100 | ||
+ | ⇤─0010 | ||
+ | 0001 0011 0101 0111 1001 ... | ||
+ | |||
+ | 「a1~a7 の和」を求めるときに足される箇所。7を表す " | ||
+ | |||
+ | ⇤─←─←─←─←─←─←─1000 | ||
+ | ⇤─←─←【0100】 | ||
+ | ⇤─0010 | ||
+ | 0001 0011 0101 【0111】 | ||
+ | |||
=====区間に対する更新===== | =====区間に対する更新===== | ||
- | 上記のBit.add()は、点に対する更新しか行えない。では「a3~a7に一律に5を加算」などが必要な場合にどうするか。 | + | 上記のBit.add()は、点に対する更新しか行えない。では「$a_3~a_7$ に一律に5を加算」などが必要な場合にどうするか。 |
====区間の和が必要ない場合==== | ====区間の和が必要ない場合==== | ||
行 65: | 行 80: | ||
区間の和は必要なく、ある指定した位置の値だけわかれば良い場合。つまり、 | 区間の和は必要なく、ある指定した位置の値だけわかれば良い場合。つまり、 | ||
- | * asからatまでに一律xを加算(1≤s≤t≤n) | + | * as から at までに一律 x を加算(1≤s≤t≤n) |
- | * aiの値を得る(1≤i≤n) | + | * ai の値を得る(1≤i≤n) |
この場合は、差分に着目することで、BITをそのまま利用できる。(上記pdf参照) | この場合は、差分に着目することで、BITをそのまま利用できる。(上記pdf参照) | ||
- | * $s$~$tに一律xを加算→「sにx、t+1に-x$を加算」 | + | * $a_s~a_tに一律xを加算→「sにx、t+1に-x$ を加算」 |
- | * 位置$iの値を取得→「1$~$i$の合計を取得」 | + | * $a_iの値を取得→「1~i$ の合計を取得」 |
- | なお、見ての通り添え字がn+1まで参照される可能性があるので、便宜上、Bitのサイズは1大きい値で作っておく | + | なお、見ての通り添え字が n+1 まで参照される可能性があるので、便宜上、BITのサイズは1大きい値で作っておく |
====区間の和も欲しい場合==== | ====区間の和も欲しい場合==== | ||
- | * $a_sからa_t$までに一律xを加算(1≤s≤t≤n) | + | * $a_s~a_tに一律xを加算(1 \le s \le t \le n$) |
- | * $a_sからa_t$までの合計を得る(1≤s≤t≤n) | + | * $a_s~a_tの合計を得る(1 \le s \le t \le n$) |
< | < |