I was wondering if a Fenwick Tree (or Binary Indexed Tree) can be modified to:
1) Increment the frequency all elements in a range by a certain amount
2) Query the frequency of a single element.
This is as opposed to the traditional Fenwick Tree where updates are done on a single element and queries are done over a range (kind of like an inverse Fenwick Tree).
Sure!
Fenwick tree allows you to do these operations in O(log n):
Here’s a simple implementation of a Fenwick tree in C++:
Now forget about the internals of the Fenwick tree and focus on the problem. When using Fenwick tree, just imagine it literally stores an array of frequencies and somehow magically does both operations in O(log n). Function update modifies the frequency of a single element and query returns sum of frequencies of first x elements.
So in the ‘traditional’ problem you had these operations:
Now, instead of storing frequency of each single element, let’s store differences between frequencies of adjacent elements.
These are the new operations:
When incrementing frequencies in range [a..b], just increment difference at index a and decrement difference at index b+1. This is also like saying: increment all frequencies in range [a..infinity] and decrement all frequencies in range [b+1..infinity].
To get the frequency of the element at index x, just sum all differences of frequencies in range [0..x].