mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-12-08 19:06:00 +00:00
73 lines
1.6 KiB
JavaScript
73 lines
1.6 KiB
JavaScript
export default class FenwickTree {
|
|
/**
|
|
* Constructor creates empty fenwick tree of size 'arraySize',
|
|
* however, array size is size+1, because index is 1-based.
|
|
*
|
|
* @param {number} arraySize
|
|
*/
|
|
constructor(arraySize) {
|
|
this.arraySize = arraySize;
|
|
|
|
// Fill tree array with zeros.
|
|
this.treeArray = Array(this.arraySize + 1).fill(0);
|
|
}
|
|
|
|
/**
|
|
* Adds value to existing value at position.
|
|
*
|
|
* @param {number} position
|
|
* @param {number} value
|
|
* @return {FenwickTree}
|
|
*/
|
|
increase(position, value) {
|
|
if (position < 1 || position > this.arraySize) {
|
|
throw new Error('Position is out of allowed range');
|
|
}
|
|
|
|
for (let i = position; i <= this.arraySize; i += (i & -i)) {
|
|
this.treeArray[i] += value;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Query sum from index 1 to position.
|
|
*
|
|
* @param {number} position
|
|
* @return {number}
|
|
*/
|
|
query(position) {
|
|
if (position < 1 || position > this.arraySize) {
|
|
throw new Error('Position is out of allowed range');
|
|
}
|
|
|
|
let sum = 0;
|
|
|
|
for (let i = position; i > 0; i -= (i & -i)) {
|
|
sum += this.treeArray[i];
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* Query sum from index leftIndex to rightIndex.
|
|
*
|
|
* @param {number} leftIndex
|
|
* @param {number} rightIndex
|
|
* @return {number}
|
|
*/
|
|
queryRange(leftIndex, rightIndex) {
|
|
if (leftIndex > rightIndex) {
|
|
throw new Error('Left index can not be greater than right one');
|
|
}
|
|
|
|
if (leftIndex === 1) {
|
|
return this.query(rightIndex);
|
|
}
|
|
|
|
return this.query(rightIndex) - this.query(leftIndex - 1);
|
|
}
|
|
}
|