fenwick tree Algorithm
The Fenwick tree, also known as a binary indexed tree, is an advanced data structure that can efficiently perform prefix sums and cumulative frequency operations on an array of numbers. This algorithm was developed by Peter M. Fenwick in 1994 as an efficient solution for managing the frequency tables found in various compression algorithms. The Fenwick tree algorithm is particularly useful in applications requiring frequent updates and queries, such as computational geometry, range-based queries, and data manipulation in databases.
The core idea behind the Fenwick tree algorithm is based on the binary representation of integers and the ability to manipulate them to access the required data quickly. This data structure stores partial sums of the original array in a compact, binary tree-like structure. Specifically, each node in the Fenwick tree is responsible for storing the sum of a range of values in the original array. To perform prefix sum queries or update operations, the algorithm traverses the tree, following parent-child relationships that are determined by the least significant bit of the indices. This traversal allows the Fenwick tree to perform both update and sum operations in logarithmic time complexity (O(log n)), making it significantly faster than ordinary prefix sum arrays or segment trees.
class FenwickTree:
def __init__(self, SIZE): # create fenwick tree with size SIZE
self.Size = SIZE
self.ft = [0 for i in range(0, SIZE)]
def update(self, i, val): # update data (adding) in index i in O(lg N)
while i < self.Size:
self.ft[i] += val
i += i & (-i)
def query(self, i): # query cumulative data from index 0 to i in O(lg N)
ret = 0
while i > 0:
ret += self.ft[i]
i -= i & (-i)
return ret
if __name__ == "__main__":
f = FenwickTree(100)
f.update(1, 20)
f.update(4, 4)
print(f.query(1))
print(f.query(3))
print(f.query(4))
f.update(2, -5)
print(f.query(1))
print(f.query(3))