Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to build a Fenwick tree in O(n)?

Fenwick tree is a data structure which allows two kind of operations (you can augment it with more operations):

  • point update update(index, value)
  • prefix sum query(index)

Both of the operations are in O(log(n)) where n is the size of an array. I have no problems understanding how to do both operations and the logic behind them.


My question is how can I initialize a Fenwick tree from an array. Clearly I can achieve this in O(nlog(n)), by calling n times update(i, arr[i]), but is there a way to initialize it in O(n).


Why am I asking this if wikipedia tells that you can initialize in nlog(n)? Because the article is so rudimentary, that I am not sure whether it is the best complexity one can achieve. Also drawing parallels with naive heap creation which is done by populating the heap one by one and can be achieved in O(nlog(n)) versus smart heap initialization in O(n) gives me hope that something similar can be done in Fenwick tree.

like image 470
Salvador Dali Avatar asked Jun 26 '15 08:06

Salvador Dali


People also ask

What is the space complexity of the Fenwick tree?

Segment Trees require a space complexity of O(4*N) , while fenwick trees only needs O(N) , and so it's also useful when being used as a hash map.

How does a Fenwick tree work?

A Fenwick tree is most easily understood by considering a one-based array. Each element whose index i is a power of 2 contains the sum of the first i elements. Elements whose indices are the sum of two (distinct) powers of 2 contain the sum of the elements since the preceding power of 2.

Is Fenwick tree better than segment tree?

Fenwick trees are faster and extremely simple to implement. The asymptotic bounds are equivalent, but the most basic query and update code is almost branchless, non-recursive, and uses very few operations. The segment tree versions of this can be made almost as fast, but this does take extra effort.

Is Fenwick tree useful?

A Fenwick tree or binary indexed tree is a data structure that helps compute prefix sums efficiently. Computing prefix sums are often important in various other algorithms, not to mention several competitive programming problems. For example, they are used to implement the arithmetic coding algorithm.


1 Answers

[EDIT: I had things "upside-down" -- fixed now!]

Yes. Loop through the n array items in increasing index order, always adding the sum only to the next smallest index that it should be added to, instead of to all of them:

for i = 1 to n:     j = i + (i & -i)     # Finds next higher index that this value should contribute to     if j <= n:         x[j] += x[i] 

This works because although every value contributes to several range sums, after processing the bottommost range sum that the value contributes to (which actually requires no "processing", since the sum is already in there), we no longer need to maintain its separate identity -- it can safely be merged with all other values that contribute to the remaining range sums.

TTBOMK this algorithm is "new" -- but then I haven't looked very hard ;)

like image 140
j_random_hacker Avatar answered Sep 30 '22 00:09

j_random_hacker