Binary Indexed Tree (BIT)は、配列の区間和クエリと要素の更新を効率的に処理するデータ構造です。
通常の配列では区間和の計算にO(n)時間がかかりますが、BITを使用することでO(log n)で実行できます。
| 操作 | 通常の配列 | BIT |
|---|---|---|
| 要素の更新 | O(1) | O(log n) |
| 区間和クエリ | O(n) | O(log n) |
| 空間計算量 | O(n) | O(n) |
BITの核心は最下位ビット(LSB)の概念です。各インデックスが管理する範囲は、そのインデックスの二進表現の最下位の1ビットによって決まります。
LSB(x) = x & (-x) 例: 6 (110₂) の LSB = 110₂ & 010₂ = 010₂ = 2 8 (1000₂) の LSB = 1000₂ & 1000₂ = 1000₂ = 8
class BIT {
constructor(n) {
this.n = n;
this.tree = new Array(n + 1).fill(0);
}
// LSB(最下位ビット)を取得
lowbit(x) {
return x & (-x);
}
// インデックス i に値 delta を加算
update(i, delta) {
while (i <= this.n) {
this.tree[i] += delta;
i += this.lowbit(i);
}
}
// インデックス 1 から i までの累積和を取得
query(i) {
let sum = 0;
while (i > 0) {
sum += this.tree[i];
i -= this.lowbit(i);
}
return sum;
}
// インデックス l から r までの区間和を取得
rangeQuery(l, r) {
return this.query(r) - this.query(l - 1);
}
}