forked from realpacific/algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPartialSumUsingFenwickTree.kt
76 lines (65 loc) · 2.13 KB
/
PartialSumUsingFenwickTree.kt
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package algorithmdesignmanualbook.partialsum
import algorithmdesignmanualbook.print
import java.util.*
import kotlin.experimental.and
import kotlin.experimental.inv
/**
* Let A be an array of n real numbers. Design an algorithm to perform any sequence of the following operations:
* • Add(i,y) – Add the value y to the ith number.
* • Partial-sum(i) – Return the sum of the first i numbers
* Each operation must take O(logn).
*
* Fenwick Tree or Binary Indexed Tree is a tree containing n+1 nodes.
* Each node's parent is right most 1 flipped i.e
* * 8 -> 1000 so parent is 0000 (0)
* * 7 -> 0111 so parent is 0110 (6)
* * 10 -> 1010 so parent is 1000 (8)
* * 5 -> 0101 so parent is 0100 (4)
* Sum can be obtained by (0..5) -> tree[6] + tree[4] + tree[0] i.e index+1 and then go upwards to parents
*
* To get the parent:
* * 2's complement (Flip all bits and add 1)
* * AND it with original number
* * Subtract it from original number
*
* 7 (111) ---(step 1)---> 000+1=001 ---(AND 111)-->001 --(Subtract from 111)--->110
*
*/
class PartialSumUsingFenwickTree(private val values: Array<Int>) {
val tree = Array(values.size + 1) { 0 }
init {
construcFenwickTree()
}
fun removeLastSetBit(byte: Byte): Byte {
return (byte - byte.and(byte.inv().plus(0b1).toByte())).toByte()
}
private fun construcFenwickTree() {
values.forEachIndexed { index, value ->
update(index, value)
}
}
private fun update(index: Int, value: Int) {
var bTreeIndex = index + 1
while (bTreeIndex <= values.size) {
tree[bTreeIndex] += value
bTreeIndex += bTreeIndex.and(-bTreeIndex)
}
}
fun getSum(index: Int): Int {
var sum = 0
var bIndex = index + 1
while (bIndex > 0) {
sum += tree[bIndex]
bIndex -= bIndex.and(-bIndex)
}
return sum
}
}
fun main() {
val solution = PartialSumUsingFenwickTree(arrayOf(1, 2, 3, 4, 5, 6))
solution.removeLastSetBit(0b111).print { it.toString(2) }
solution.tree.print {
Arrays.toString(it)
}
solution.getSum(2).print()
}