Fenwick Tree |
Fenwick Tree
More info: https://en.wikipedia.org/wiki/Fenwick_tree
Add a value to index in O(lg N)
index (int): index to add value to value (int): value to add to index
None
>>> f = FenwickTree([1, 2, 3, 4, 5])
>>> f.add(0, 1)
>>> f.add(1, 2)
>>> f.add(2, 3)
>>> f.add(3, 4)
>>> f.add(4, 5)
>>> f.get_array()
[2, 4, 6, 8, 10]
Get value at index in O(lg N)
index (int): index to get the value
int: Value of element at index
>>> a = [i for i in range(128)]
>>> f = FenwickTree(a)
>>> res = True
>>> for i in range(len(a)):
... res = res and f.get(i) == a[i]
>>> res
True
Get the Normal Array of the Fenwick tree in O(N)
list: Normal Array of the Fenwick tree
>>> a = [i for i in range(128)]
>>> f = FenwickTree(a)
>>> f.get_array() == a
True
Initialize the Fenwick tree with arr in O(N)
arr (list): list of elements to initialize the tree with
None
>>> a = [1, 2, 3, 4, 5]
>>> f1 = FenwickTree(a)
>>> f2 = FenwickTree(size=len(a))
>>> for index, value in enumerate(a):
... f2.add(index, value)
>>> f1.tree == f2.tree
True
Prefix sum of all elements in [0, right) in O(lg N)
right (int): right bound of the query (exclusive)
int: sum of all elements in [0, right)
>>> a = [i for i in range(128)]
>>> f = FenwickTree(a)
>>> res = True
>>> for i in range(len(a)):
... res = res and f.prefix(i) == sum(a[:i])
>>> res
True
Query the sum of all elements in [left, right) in O(lg N)
left (int): left bound of the query (inclusive) right (int): right bound of the query (exclusive)
int: sum of all elements in [left, right)
>>> a = [i for i in range(128)]
>>> f = FenwickTree(a)
>>> res = True
>>> for i in range(len(a)):
... for j in range(i + 1, len(a)):
... res = res and f.query(i, j) == sum(a[i:j])
>>> res
True
Find the largest index with prefix(i) <= value in O(lg N) NOTE: Requires that all values are non-negative!
value (int): value to find the largest index of
-1: if value is smaller than all elements in prefix sum int: largest index with prefix(i) <= value
>>> f = FenwickTree([1, 2, 0, 3, 0, 5])
>>> f.rank_query(0)
-1
>>> f.rank_query(2)
0
>>> f.rank_query(1)
0
>>> f.rank_query(3)
2
>>> f.rank_query(5)
2
>>> f.rank_query(6)
4
>>> f.rank_query(11)
5
Set the value of index in O(lg N)
index (int): index to set value to value (int): value to set in index
None
>>> f = FenwickTree([5, 4, 3, 2, 1])
>>> f.update(0, 1)
>>> f.update(1, 2)
>>> f.update(2, 3)
>>> f.update(3, 4)
>>> f.update(4, 5)
>>> f.get_array()
[1, 2, 3, 4, 5]