-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsegmentTree.js
More file actions
58 lines (47 loc) · 1.59 KB
/
Copy pathsegmentTree.js
File metadata and controls
58 lines (47 loc) · 1.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class SegmentTree {
constructor(operation, operationFallBack, n = null, inputArray = null) {
this.operation = operation
this.operationFallback = operationFallBack
if (n == null && inputArray == null) {
throw new Error("Size and Input array can not be null at same time")
} else if (n == null) {
this.inputSize = inputArray.length
this.inputArray = inputArray
} else this.inputSize = n;
if (Math.log2(this.inputSize) % 1 === 0) this.size = 2 * this.inputSize;
else this.size = 1 << (this.inputSize.toString(2).length + 1);
this.auxSize = this.size - this.inputSize
this.tree = new Array(this.size).fill(operationFallBack)
if (n == null) this.build()
}
build() {
for (let i = 0; i < this.inputSize; i++) {
this.update(i, this.inputArray[i])
}
}
update(index, value) {
if (index >= this.inputSize) return
let ind = index + this.auxSize
this.tree[ind] = value
while (ind > 1) {
let parent_i = ind >> 1
this.tree[parent_i] = this.operation(this.tree[ind], this.tree[ind ^ 1])
ind = parent_i
}
}
query(left, right) {
if (left > right) return this.operationFallback
if (left < 0) left = 0
if (right >= this.inputSize) right = this.inputSize - 1
let l = left + this.auxSize, r = right + this.auxSize
let res = this.operationFallback
while (l <= r) {
if ((l & 1) === 1) res = this.operation(res, this.tree[l])
if ((r & 1) !== 1) res = this.operation(res, this.tree[r])
l = (l + 1) >> 1
r = (r - 1) >> 1
}
return res
}
}
module.exports = SegmentTree