Professional Documents
Culture Documents
Range Updates With BIT - Fenwick Tree - Everything Under The Sun
Range Updates With BIT - Fenwick Tree - Everything Under The Sun
Range Updates With BIT - Fenwick Tree - Everything Under The Sun
A blog on CS concepts
Given an array A of N numbers, we need to support adding a value v to any element A[p] and
querying the sum of numbers A[a] + A[a+1] + … + A[b], both operations in O(log N). Let ft[N+1]
denotes the underlying fenwick tree.
1 # Add v to A[p]
2 update(p, v):
3 for (; p <= N; p += p&(-p))
4 ft[p] += v
5
6 # Return sum A[1...b]
7 query(b):
8 sum = 0
9 for(; b > 0; b -= b&(-b))
10 sum += ft[b]
11 return sum
12
13 # Return sum A[a...b]
14 query(a, b):
15 return query(b) - query(a-1)
view raw Point Updates and Range Queries.py hosted with ❤ by GitHub
Given an array A of N numbers, we need to support adding a value v to each element A[a…b] and
querying the value of A[p], both operations in O(log N). Let ft[N+1] denote the underlying fenwick
tree.
Explanation: update(p, v) will affect all p’ >= p. To limit the effect to a given range [a…b], we subtract
-v from all p’ > b by performing the operation update(b+1, -v).
Given an array A of N numbers, we need to support adding a value v to each element A[a…b] and
querying the sum of numbers A[a…b], both operations in O(log N). This can be done by using two
BITs B1[N+1], B2[N+1].
1 update(ft, p, v):
2 for (; p <= N; p += p&(-p))
3 ft[p] += v
4
5 # Add v to A[a...b]
6 update(a, b, v):
7 update(B1, a, v)
8 update(B1, b + 1, -v)
9 update(B2, a, v * (a-1))
10 update(B2, b + 1, -v * b)
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 2/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
11
12 query(ft, b):
13 sum = 0
14 for(; b > 0; b -= b&(-b))
15 sum += ft[b]
16 return sum
17
18 # Return sum A[1...b]
19 query(b):
20 return query(B1, b) * b - query(B2, b)
21
22 # Return sum A[a...b]
23 query(a, b):
24 return query(b) - query(a-1)
view raw Range Updates and Range Queries.py hosted with ❤ by GitHub
Explanation:
BIT B1 is used like in the earlier case with range updates/point queries such that query(B1, p) gives
A[p].
Consider a range update query: Add v to [a…b]. Let all elements initially be 0. Now, Sum(1…p) for
different p is as follows:
1 <= p < a : 0
a <= p <= b : v * (p – (a – 1))
b < p <= N : v * (b – (a – 1))
Thus, for a given index p, we can find Sum(1…p) by subtracting a value X from p * Sum(p,p)
(Sum(p,p) is the actual value stored at index p) such that
References:
http://apps.topcoder.com/forums/?module=Thread&threadID=715842&start=0&mc=8
(http://apps.topcoder.com/forums/?module=Thread&threadID=715842&start=0&mc=8)
http://programmingcontests.quora.com/Tutorial-Range-Updates-in-Fenwick-Tree
(http://programmingcontests.quora.com/Tutorial-Range-Updates-in-Fenwick-Tree)
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 3/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
This entry was posted in Data Structures and tagged binary indexed tree, BIT, C++ implementation,
explanation, fenwick tree, HORRIBLE Spoj, point updates/range queries, range updates/point queries, range
updates/range queries, UPDATEIT Spoj. Bookmark the permalink.
1. islamtahaa says:
June 21, 2015 at 4:35 pm
what if i’m updating with different values not with v i.e. for every element i update with it’s
unique value ?
Reply
kartik kukreja says:
June 21, 2015 at 6:06 pm
BITs don’t support this operation. If you want to perform totally unrelated updates to each
element in a range, you can perform point updates for each element in the range and pay a log
n cost for each point update.
Reply
2. islamtahaa says:
June 21, 2015 at 6:10 pm
is there any tutorial or something like that, to explain this operation using segment tree ?
Reply
kartik kukreja says:
June 21, 2015 at 6:17 pm
I’ve written two posts on segment trees:
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 4/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
They don’t explain this operation directly but combine them with this idea: An update to the
tree can be a list of point updates, sorted by index, and we can split this list for left and right
children. This should solve a more general problem than a range update: updating any set of
indices with any values.
Reply
3. Anonymous says:
July 5, 2015 at 2:05 am
What if I want to update a range with minimum value?
For example if my array is 1 2 3 4 5
and my update query is (l=1,r=5,v=1) then,
for(i=l;i<=r;i++)
arr[i]=min(arr[i],v);
should take place and my final array should be
11111
Reply
kartik kukreja says:
July 5, 2015 at 11:07 am
BITs have one purpose: supporting range sum queries and updates in O(log N) complexity.
Sure we can use some hacks to do more with them but we should always try to use a data
structure that naturally supports the operations we want to perform. A segment tree will
naturally support this operation so you should try to use it.
Reply
4. Eknoor Jassal says:
July 6, 2015 at 12:02 pm
The explanations are very brief. Examples would make them better
Reply
5. Shivam Aggarwal says:
July 7, 2015 at 2:17 am
if we’ve non zero elements in input array then how the code will change? specifically in 3rd case
Range update and Range queries ?
Reply
kartik kukreja says:
July 7, 2015 at 9:02 am
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 5/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
A rather simple approach is to start with an empty BIT (all elements 0) and then update the
value at each index. It’s complexity is O(N log N). I don’t know if there’s a better approach that
can do it in O(N).
Reply
Shivam Aggarwal says:
July 7, 2015 at 3:03 pm
Question i was trying was.. suppose I/p array is 1 2 3 4 and q queries are there… p 1 2
means print sum from 1 to 2 & u 1 3 4 means add 4 to the elements from 1 to 3… the 3rd
case isn’t working on this any idea why ??
Reply
kartik kukreja says:
July 7, 2015 at 3:38 pm
Sure it’s working. Use the following code to initialize the BIT:
Reply
6. Suraj Prakash says:
July 11, 2015 at 9:26 pm
if we wanted to change value of array to a specific value i.e. (A[i]…..A[j]) = x , how can we
implement that
Reply
kartik kukreja says:
July 11, 2015 at 10:02 pm
A straightforward approach is to query for the value in each index of the range and update the
difference from the desired value.
Reply
7. Anonymous says:
July 23, 2015 at 8:55 pm
Awesome post…Helped me understand the beautiful Fenwick Tree easily.
Reply
8. Reva Yoga Pradana says:
August 9, 2015 at 10:51 pm
aweseome tutorial, thanks
Reply
9. RDR says:
August 20, 2015 at 12:49 am
Hey, can you please explain how range update point query is working, I am confused on how
query(b) is giving the value present at A[b]
Reply
kartik kukreja says:
August 20, 2015 at 10:24 am
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 6/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
The question as I understand is this: why the same query(x) function calculates sum(A[1..x])
for point-update-range-query while it calculates A[x] for range-update-point-query?
update(x,v) and query(x) functions are common to both the cases so they must have the same
behavior too. update(x,v) adds v to some elements ft[i] (i≥x) such that when you call query(i)
(i≥x), you will see this update v exactly once and thus count it exactly once. query(x) adds
some elements ft[i] (i≤x) such that each update to any element i≤x is seen exactly once.
For the point-update-range-query case, all update(x,v) are visible to x’≥x so when you call
query(c), you effectively add all the updates applied to all elements 1≤i≤c which is nothing but
the sum of A[1..c].
Reply
Antonio says:
September 18, 2015 at 2:10 am
Hi Kartik,
it all makes sense what you have written above, but you mentioned that frequencies stored
in a BIT have different meaning.
ex. Let tree be an array where we represent our BIT
1. in point update – range query: tree[x] represents cumulative frequency for elements with
values
{ x – 2^r + 1, … , x } , where r is the position of the right-most non-zero bit. so tree[6] stores
cumulative frequency for values 5 and 6. (6 in binary is 110, r=1, 6 – 2^1 + 1 = 5).
but, in range update – point query what does exactly tree[x] represents, what is the
meaning of tree[x]?
Thanks in advance.
Reply
kartik kukreja says:
September 19, 2015 at 9:18 pm
It basically means the same thing (still a cumulative frequency table) but the semantics
are now different.
Suppose you update index 2 with value 5, now when you query for any index >= 2, it’d
return 5+whatever it would have returned earlier. You can get the range query behavior
as query(a,b) = query(b) – query(a-1).
With range update-point query for an interval [2,4] with update 5, we update index 2
with value 5 and index 5(4+1) with value -5. So if you query for an index x < 2, you
won't see the update 5. If you query for 2<=x 4, you’ll see two updates 5 and -5 which
cancel each other.
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 7/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
So the meaning of what is stored in an element in a BIT hasn’t changed; what has
changed is how we are using it.
Reply
Antonio says:
September 20, 2015 at 3:06 am
Sorry for borthering, but I didn’t formulate my question really well.
ex. In point update – range query tree[6] stores how many times does the values 5
and 6 appear in array.
What do values stored in tree[x] , for range update – point query , mean?
It’s illogical to think that a BIT will store count of each value separately because then
building a BIT for even a 1-element array could take a billion integers if the updates
can be anything. Further, nowhere do we say that the updates must only be positive
integers; they can be negative so the array elements can be negative.
So, even in range update-point query, tree[6] stores the sum of values at array
indices 5 and 6.
10. competitivecoder says:
September 15, 2015 at 12:03 am
Sir,Do we loose original array when update point or range update,amarite?
Reply
kartik kukreja says:
September 15, 2015 at 7:46 am
BIT doesn’t maintain the updated array for constant time access to its elements. But you can
query for the updated value of each element in O(log N).
Reply
competitivecoder says:
September 15, 2015 at 8:37 am
Sorry I think I was not clear enough.My question was–If we call update like update(i,X) so
we have A[i] as A[i]+(X) as new value.For example A[1]=5,A[2]=10,A[3]=15,….calling
update(1,5) so now A[1] will be 10.This was my question
Reply
kartik kukreja says:
September 15, 2015 at 8:39 am
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 8/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
Are you saying that you want the original values from the BIT, before any updates were
applied to it? No, BIT does not provide that. You can just keep a copy of the original
values separately in an array if you want them.
Reply
competitivecoder says:
September 16, 2015 at 12:13 am
Firstly I would like to apologize for being so dumb sir,but believe me I am facing lot
of confusions 😦
.Please answer these question that I am not getting regarding this
difficult data structure.
1)When we say update a[i] with x(i.e a[i]+=x) by calling update function,Do we
really add anything to the actual array A at index i or we make modifications to the
bit tree so that conceptually it will make similar sense like adding x to a[i].
And again I am very embarrassed to bother you again and again and again.
I hope that helps. Please do let me know if you need more help.
11. competitivecoder says:
September 16, 2015 at 10:06 am
Sir first of all thanks for such warmth reply . 🙂
Question link ->https://www.hackerearth.com/problem/algorithm/help-ashu-1/description/
My solution link->https://www.hackerearth.com/submission/2544059/
Sir,I have small doubt left in this question.Please have a look at I will be out of here I swear .In 😦
this question I know how to do when query=1 and query=2.But have small doubt in query=0.In
query 0 we are asked to change array at some index l to x(i.e a[l]=x).So we want our original array
to get changed.So what we will do is we change our original array a[l] to x as well as our BIT
according to changes made in our original array as I did(see my submission).But say we have
scenario in which we have query=0 and in that query we are asked to change original array to X
for the whole interval like(if query==0 change original array to X for the interval from [L,R] how
efficiently we can do this ??)
Reply
kartik kukreja says:
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 9/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
Reply
12. competitivecoder says:
September 17, 2015 at 10:33 am
Thankssssss…. Sorry for spamming but I am so much excited now.I finally got it. 🙂🙂🙂🙂🙂
🙂
Reply
13. Ravi says:
October 7, 2015 at 3:50 pm
Hi,
Is my thinking right ?
and if I want to perform a mix of these in a random order {op1, op2, op1, op3, op3, …. },
that would not make sense ?
Thanks,
Ravi
Reply
kartik kukreja says:
October 7, 2015 at 3:56 pm
Range update range query (mode 3) is superset of the other two modes because a point
query/update is also a range query/update where the range contains only that point [i,i].
Point update/query are basically special cases, for which we can optimize as we have in
modes 1 and 2.
If you have a mix of operations, you’ll have to use range update-range query.
Reply
14. Jin Xiang says:
November 24, 2015 at 1:51 am
Nice article. I am also reading your article on segment tree lazy propagation. Is it possible to use
BIT to solve the FLIPCOIN problem (which was an example of segment tree lazy propagation)?
Thanks.
Reply
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 10/11
3/31/24, 2:01 PM Range updates with BIT / Fenwick Tree | Everything Under The Sun
Reply
Jin Xiang says:
November 24, 2015 at 7:47 pm
Thank you very much for your reply. I noticed that in the following topcoder tutorial:
https://www.topcoder.com/community/data-science/data-science-tutorials/binary-
indexed-trees/#prob
BIT has been used to solve range update point query problem (which is similar but simpler
than FLIPCOIN). Is it possible to extend it to solve FLIPCOIN problem?
Reply
kartik kukreja says:
November 24, 2015 at 8:07 pm
BIT does support range update-point query or even range update-range query but the
updates are basically sums (adding/subtracting some value). FLIPCOIN requires a
much more complicated operation: flip (xor with 1) and count. BIT is not suitable for
this.
Reply
15. Akshit Chopra says:
December 31, 2015 at 12:14 am
how does the same QUERY code give range sum A[1..p] in case 1 while point value A[p] in case 2
..could you explain ?
Reply
kartik kukreja says:
December 31, 2015 at 8:22 am
Please look at this comment: https://kartikkukreja.wordpress.com/2013/12/02/range-
updates-with-bit-fenwick-tree/comment-page-2/#comment-5442
Reply
16. Pingback: Bit fiddling: Exercise that grey matter | Everything Under The Sun
Reply
Kartik Kukreja says:
June 13, 2016 at 8:05 am
I don’t know if you made the comment before the update but the code has been changed to
return the BIT sum + A[b].
Reply
https://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/#more-420 11/11