0% found this document useful (0 votes)
66 views162 pages

Fenwick Tree

A Fenwick tree is a data structure that allows for efficient range sum queries and point updates on a static array. It supports range sum queries in O(log(n)) time by having each cell in the Fenwick tree responsible for summing a particular range of values in the original array. Point updates can also be performed quickly in O(log(n)) time by updating relevant cells in the Fenwick tree. This makes it more efficient than a simple prefix sum array which requires O(n) time for updates.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
66 views162 pages

Fenwick Tree

A Fenwick tree is a data structure that allows for efficient range sum queries and point updates on a static array. It supports range sum queries in O(log(n)) time by having each cell in the Fenwick tree responsible for summing a particular range of values in the original array. Point updates can also be performed quickly in O(log(n)) time by updating relevant cells in the Fenwick tree. This makes it more efficient than a simple prefix sum array which requires O(n) time for updates.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 162

Fenwick Tree

(Binary Indexed Tree)


William Fiset
Outline
• Discussion & Examples

• Data structure motivation

• What is a Fenwick tree?

• Complexity analysis

• Implementation details

• Range query

• Point Updates

• Fenwick tree construction

• Code Implementation
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

Sum of A from [2,7) = 6 + 1 + 0 + -4 + 11 = 14


Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

Sum of A from [2,7) = 6 + 1 + 0 + -4 + 11 = 14


Sum of A from [0,4) = 5 + -3 + 6 + 1 = 9
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

Sum of A from [2,7) = 6 + 1 + 0 + -4 + 11 = 14


Sum of A from [0,4) = 5 + -3 + 6 + 1 = 9
Sum of A from [7,8) = 6 = 6
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 ∅ ∅ ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 ∅ ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 ∅ ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 ∅ ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 ∅ ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 ∅ ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 ∅ ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 ∅

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 31

Let P be an array containing all


the prefix sums of A.
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 31

Sum of A from [2,7) = P[7] - P[2] = 16 - 2 = 14


Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 31

Sum of A from [2,7) = P[7] - P[2] = 16 - 2 = 14


Sum of A from [0,4) = P[4] - P[0] = 9 - 0 = 9
Fenwick Tree
Motivation
Given an array of integer values compute
the range sum between index [i, j).
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 31

Sum of A from [2,7) = P[7] - P[2] = 16 - 2 = 14


Sum of A from [0,4) = P[4] - P[0] = 9 - 0 = 9
Sum of A from [7,8) = P[8] - P[7] = 22 - 16 = 6
Fenwick Tree
Motivation
Question: What about if we want to update
our initial array with some new value?
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 0 -4 11 6 2 7

P = 0 5 2 8 9 9 5 16 22 24 31
Fenwick Tree
Motivation
Question: What about if we want to update
our initial array with some new value?
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 3 -4 11 6 2 7

P = 0 5 2 8 9 12 8 19 25 27 34

A[4] = 3
Fenwick Tree
Motivation
Question: What about if we want to update
our initial array with some new value?
0 1 2 3 4 5 6 7 8 9
A = 5 -3 6 1 3 -4 11 6 2 7

P = 0 5 2 8 9 12 8 19 25 27 34

A prefix sum array is great for static


arrays, but takes O(n) for updates.
What is a
Fenwick Tree?
A Fenwick Tree (also called Binary
Indexed Tree) is a data structure that
supports sum range queries as well as
setting values in a static array and
getting the value of the prefix sum up
some index efficiently.
Complexity
Construction O(n)

Point Update O(log(n))

Range Sum O(log(n))

Range Update O(log(n))

Adding Index N/A

Removing Index N/A


Fenwick Tree
Range Queries
William Fiset
16 100002
15 011112 _
Unlike a regular array, in
14 011102 _
a Fenwick tree a specific
13 011012 cell is responsible for
other cells as well.
_

12 011002
_

11 010112
_

10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _
Unlike a regular array, in
14 011102 _
a Fenwick tree a specific
13 011012 cell is responsible for
other cells as well.
_

12 011002
_

11 010112
_

10 010102 The position of the least


significant bit (LSB)
_

9 010012
determines the range of
_

8 010002
responsibility that cell has
_

7 _ 001112 to the cells below itself.


6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _
Unlike a regular array, in
14 011102 _
a Fenwick tree a specific
13 011012 cell is responsible for
other cells as well.
_

12 011002
_

11 010112
_

10 010102 The position of the least


significant bit (LSB)
_

9 010012
determines the range of
_

8 010002
responsibility that cell has
_

7 _ 001112 to the cells below itself.


6 _ 001102
5 _ 001012 Index 12 in binary is: 11002
4 _ 001002
3 000112 LSB is at position 3, so this
index is responsible for 23-1 = 4
_

2 000102
cells below itself.
_

1 _ 000012
16 100002
15 011112 _
Unlike a regular array, in
14 011102 _
a Fenwick tree a specific
13 011012 cell is responsible for
other cells as well.
_

12 011002
_

11 010112
_

10 010102 The position of the least


significant bit (LSB)
_

9 010012
determines the range of
_

8 010002
responsibility that cell has
_

7 _ 001112 to the cells below itself.


6 _ 001102
5 _ 001012 Index 10 in binary is: 10102
4 _ 001002
3 000112 LSB is at position 2, so this
index is responsible for 22-1 = 2
_

2 000102
cells below itself.
_

1 _ 000012
16 100002
15 011112 _
Unlike a regular array, in
14 011102 _
a Fenwick tree a specific
13 011012 cell is responsible for
other cells as well.
_

12 011002
_

11 010112
_

10 010102 The position of the least


significant bit (LSB)
_

9 010012
determines the range of
_

8 010002
responsibility that cell has
_

7 _ 001112 to the cells below itself.


6 _ 001102
5 _ 001012 Index 11 in binary is: 10112
4 001002
LSB is at position 1, so this
_

3 000112
index is responsible for 21-1 = 1
_

2 000102
cell (itself).
_

1 _ 000012
16 100002
15 011112 _

14 011102 _

13 011012
_

12 011002
_

Blue bars represent the


11 010112
_

range of responsibility
10 010102
_
for that cell NOT value.
9 _ 010012
8 010002
_

All odd numbers have a their


7 _ 001112 first least significant bit set
6 _ 001102 in the ones position, so they are
5 _ 001012 only responsible for themselves.
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _

14 011102 _

13 011012
_

12 011002
_

Blue bars represent the


11 010112
_

range of responsibility
10 010102
_
for that cell NOT value.
9 _ 010012
8 _ 010002
7 001112 Numbers with their least
significant bit in the second
_

6 001102
position have a range of two.
_

5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _

14 011102 _

13 011012
_

12 011002
_

Blue bars represent the


11 010112
_

range of responsibility
10 010102
_
for that cell NOT value.
9 _ 010012
8 _ 010002
7 001112 Numbers with their least
significant bit in the third
_

6 001102
position have a range of four.
_

5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _

14 011102 _

13 011012
_

12 011002
_

Blue bars represent the


11 010112
_

range of responsibility
10 010102
_
for that cell NOT value.
9 _ 010012
8 _ 010002
7 001112 Numbers with their least
significant bit in the fourth
_

6 001102
position have a range of eight.
_

5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002
15 011112 _

14 011102 _

13 011012
_

12 011002
_

Blue bars represent the


11 010112
_

range of responsibility
10 010102
_
for that cell NOT value.
9 _ 010012
8 010002
Numbers with their least
_

7 _ 001112 significant bit in the


6 _ 001102 fifth position have a range
5 _ 001012 of sixteen.
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

9 010012
Idea: Suppose you want to find
_

8 010002
the prefix sum of [1, i], then
_

7 _ 001112 you start at i and cascade


6 _ 001102 downwards until you reach zero
5 _ 001012 adding the value at each of
4 _ 001002 the indices you encounter.
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 7.
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 7.
8 _ 010002
7 001112
_

sum = A[7]
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 7.
8 _ 010002
7 001112
_

sum = A[7] + A[6]


6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 7.
8 _ 010002
7 001112
_

sum = A[7] + A[6] + A[4]


6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 11.
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 11.
8 _ 010002
7 _ 001112
6 _ 001102 sum = A[11]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 11.
8 _ 010002
7 _ 001112
6 _ 001102 sum = A[11] + A[10]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 11.
8 _ 010002
7 _ 001112
6 _ 001102 sum = A[11] + A[10] + A[8]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 4.
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

Find the prefix sum


9 _ 010012 up to index 4.
8 _ 010002
7 _ 001112
6 _ 001102 sum = A[4]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

In a Fenwick tree we may


14 011102 _

compute the prefix sum up to


13 011012
_

a certain index, which


12 011002
_
ultimately lets us perform
11 010112
_
range sum queries.
10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

14 011102 _

Let’s use prefix sums to


13 011012
_

compute the interval sum


12 011002
_
between [i, j].
11 010112
_

10 010102 Compute the interval sum


between [11, 15].
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

14 011102 _

Let’s use prefix sums to


13 011012
_

compute the interval sum


12 011002
_
between [i, j].
11 010112
_

10 010102 Compute the interval sum


between [11, 15].
_

9 _ 010012
8 010002
First we compute the prefix
_

7 001112
_

sum of [1, 15], then we will


6 _ 001102 compute the prefix sum of
5 _ 001012 [1,11) and get the difference.
4 _ 001002
3 _ 000112
2 000102 Not inclusive! We want
the value at position 11.
_

1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]+A[12]
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]+A[12]+A[8]
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]+A[12]+A[8]
6 _ 001102 Sum of [1,11) = A[10]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]+A[12]+A[8]
6 _ 001102 Sum of [1,11) = A[10]+A[8]
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112
Compute the interval sum
_

14 011102
between [11, 15].
_

13 011012
_

12 011002 First we compute the prefix


sum of [1, 15], then we will
_

11 010112
compute the prefix sum of
_

10 010102
_

[1,11) and get the difference.


9 _ 010012
8 _ 010002
7 _ 001112 Sum of [1,15] = A[15]+A[14]+A[12]+A[8]
6 _ 001102 Sum of [1,11) = A[10]+A[8]
5 _ 001012
4 _ 001002 Range sum:
3 _ 000112 (A[15]+A[14]+A[12]+A[8])-(A[10]+A[8])
2 _ 000102
1 _ 000012
16 100002 Range Queries
15 011112 _

14 011102 _

13 011012
Notice that in the worst case
_

12 011002
_

the cell we’re querying has a


11 010112
_

binary representation of all


10 010102
_

ones (numbers of the form 2n-1)


9 _ 010012
8 _ 010002
7 001112 Hence, it’s easy to see that
in the worst case a range
_

6 001102
query might make us have to
_

5 001012
_

do two queries that cost


4 _ 001002 log2(n) operations.
3 _ 000112
2 _ 000102
1 _ 000012
Range query algorithm
To do a range query from [i,j] both
inclusive a Fenwick tree of size N:
function prefixSum(i):
sum := 0
while i != 0:
sum = sum + tree[i]
i = i - LSB(i)
return sum

function rangeQuery(i, j):


return prefixSum(j) - prefixSum(i-1)

Where LSB returns the value of the


least significant bit.
next video: Fenwick
Tree point updates!

Implementation source code and tests can


all be found at the following link:
github.com/williamfiset/data-structures
Fenwick Tree
Point Updates
William Fiset
Last Video: Fenwick
Tree Range Queries
16 100002 Point Updates
15 011112 _

14 011102 _ Instead of querying a range to


13 011012
_
find the interval sum we want
12 011002
_
to update a cell in our array.
11 010112
_

10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102 _ Instead of querying a range to


13 011012
_
find the interval sum we want
12 011002
_
to update a cell in our array.
11 010112
Recall that with range queries
_

10 010102
_

we cascaded down from the


9 _ 010012 current index by continuously
8 _ 010002 removing the LSB.
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102 _ Instead of querying a range to


13 011012
_
find the interval sum we want
12 011002
_
to update a cell in our array.
11 010112
Recall that with range queries
_

10 010102
_

we cascaded down from the


9 _ 010012 current index by continuously
8 _ 010002 removing the LSB.
7 _ 001112
6 _ 001102 13 = 11012, 11012-00012 = 11002
5 001012
_

12 = 11002
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102 _ Instead of querying a range to


13 011012
_
find the interval sum we want
12 011002
_
to update a cell in our array.
11 010112
Recall that with range queries
_

10 010102
_

we cascaded down from the


9 _ 010012 current index by continuously
8 _ 010002 removing the LSB.
7 _ 001112
6 _ 001102 13 = 11012, 11012-00012 = 11002
5 001012
_

12 = 11002, 11002-01002 = 10002


4 _ 001002
3 _ 000112 8 = 10002
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102 _ Instead of querying a range to


13 011012
_
find the interval sum we want
12 011002
_
to update a cell in our array.
11 010112
Recall that with range queries
_

10 010102
_

we cascaded down from the


9 _ 010012 current index by continuously
8 _ 010002 removing the LSB.
7 _ 001112
6 _ 001102 13 = 11012, 11012-00012 = 11002
5 001012
_

12 = 11002, 11002-01002 = 10002


4 _ 001002
3 _ 000112 8 = 10002, 10002-10002 = 00002
2 000102
0 = 00002
_

1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
9 = 10012, 10012+00012 = 10102
_

9 _ 010012
8 010002
10 = 10102
_

7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
9 = 10012, 10012+00012 = 10102
_

9 _ 010012
8 010002
10 = 10102, 10102+00102 = 11002
_

7 _ 001112
6 _ 001102 12 = 11002
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
9 = 10012, 10012+00012 = 10102
_

9 _ 010012
8 010002
10 = 10102, 10102+00102 = 11002
_

7 _ 001112
6 _ 001102 12 = 11002, 11002+01002 = 100002
5 _ 001012
4 _ 001002 16 = 100002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
9 = 10012, 10012+00012 = 10102
_

9 _ 010012
8 010002
10 = 10102, 10102+00102 = 11002
_

7 _ 001112
6 _ 001102 12 = 11002, 11002+01002 = 100002
5 _ 001012
4 _ 001002 16 = 100002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112
Point updates are the
_

14 011102
opposite of this, we want to
_

13 011012
_

add the LSB to propagate the


12 011002
_

value up to the cells


11 010112
_

responsible for us.


10 010102
9 = 10012, 10012+00012 = 10102
_

9 _ 010012
8 010002
10 = 10102, 10102+00102 = 11002
_

7 _ 001112
6 _ 001102 12 = 11002, 11002+01002 = 100002
5 _ 001012
4 _ 001002 16 = 100002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_

9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_
6 = 01102
9 _ 010012
8 _ 010002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_
6 = 01102, 01102+00102 = 10002
9 _ 010012
8 _ 010002 8 = 10002
7 _ 001112
6 _ 001102
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_
6 = 01102, 01102+00102 = 10002
9 _ 010012
8 _ 010002 8 = 10002, 10002+10002 = 100002
7 _ 001112
6 _ 001102 16 = 100002
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_
6 = 01102, 01102+00102 = 10002
9 _ 010012
8 _ 010002 8 = 10002, 10002+10002 = 100002
7 _ 001112
6 _ 001102 16 = 100002
5 _ 001012
4 _ 001002
3 _ 000112
2 _ 000102
1 _ 000012
16 100002 Point Updates
15 011112 _

14 011102
If we add x to position 6 in
the Fenwick tree which cells
_

13 011012
do we also need to modify?
_

12 011002
_

11 010112
_

10 010102
_
6 = 01102, 01102+00102 = 10002
9 _ 010012
8 _ 010002 8 = 10002, 10002+10002 = 100002
7 _ 001112
6 _ 001102 16 = 100002
5 _ 001012 Required Updates:
4 001002
A[6] = A[6] + x
_

3 000112
A[8] = A[8] + x
_

2 000102
A[16] = A[16] + x
_

1 _ 000012
Point update algorithm
To update the cell at index i in
the a Fenwick tree of size N:

function add(i, x):


while i < N:
tree[i] = tree[i] + x
i = i + LSB(i)

Where LSB returns the value of the


least significant bit. For example:
LSB(12) = 4 because 1210 = 11002 and the
least significant bit of 11002 is 1002,
or 4 in base ten
Fenwick Tree construction
follows in next video

Implementation source code and tests can


all be found at the following link:
github.com/williamfiset/data-structures
Fenwick Tree
Construction
William Fiset
Naive Construction

Let A be an array of values. For each


element in A at index i do a point update
on the Fenwick tree with a value of A[i].
There are n elements and each point
update takes O(log(n)) for a total of
O(nlog(n)), can we do better?
12 _ 11002 -8
Linear Construction
11 _ 10112 4 Input values we wish to
10 10102 2
turn into a legitimate
Fenwick tree.
_

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5

6 _ 01102 11

5 _ 01012 3

4 _ 01002 7

3 _ 00112 -2

2 _ 00102 4

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4
Idea: Add the value in
10 10102 2
the current cell to the
_

9 _ 10012 -9 immediate cell that is


responsible for us. This
8 10002 -8
resembles what we did for
_

7 _ 01112 5 point updates but only


one cell at a time.
6 _ 01102 11

5 _ 01012 3 This will make the


4 01002 7 ‘cascading’ effect in
range queries possible
_

3 _ 00112 -2 by propagating the value


2 00102 4 in each cell throughout
the tree.
_

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2 Let i be the current index


9 10012 -9
The immediate cell above us
_

8 _ 10002 -8 is at position j given by:


7 _ 01112 5
j := i + LSB(i)
6 _ 01102 11

5 _ 01012 3 Where LSB is the Least


4 _ 01002 7 Significant Bit of i

3 _ 00112 -2

2 _ 00102 4

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 1 = 00012
6 01102 11
j = 00012 + 00012 = 00102
_

5 _ 01012 3 = 2
4 _ 01002 7

3 _ 00112 -2

2 _ 00102 4

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 1 = 00012
6 01102 11
j = 00012 + 00012 = 00102
_

5 _ 01012 3 = 2
4 _ 01002 7

3 _ 00112 -2

2 _ 00102 4+3

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 2 = 00102
6 01102 11
j = 00102 + 00102 = 01002
_

5 _ 01012 3 = 4
4 _ 01002 7

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 2 = 00102
6 01102 11
j = 00102 + 00102 = 01002
_

5 _ 01012 3 = 4
4 _ 01002 7+7

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 3 = 00112
6 01102 11
j = 00112 + 00012 = 01002
_

5 _ 01012 3 = 4
4 _ 01002 14

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 3 = 00112
6 01102 11
j = 00112 + 00012 = 01002
_

5 _ 01012 3 = 4
4 _ 01002 14+-2

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8

7 _ 01112 5 i = 4 = 01002
6 01102 11
j = 01002 + 01002 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 -8+12

7 _ 01112 5 i = 4 = 01002
6 01102 11
j = 01002 + 01002 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 4

7 _ 01112 5 i = 5 = 01012
6 01102 11
j = 01012 + 00012 = 01102
_

5 _ 01012 3 = 6
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 4

7 _ 01112 5 i = 5 = 01012
6 01102 11+3
j = 01012 + 00012 = 01102
_

5 _ 01012 3 = 6
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 4

7 _ 01112 5 i = 6 = 01102
6 01102 14
j = 01102 + 00102 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 4+14

7 _ 01112 5 i = 6 = 01102
6 01102 14
j = 01102 + 00102 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 18

7 _ 01112 5 i = 7 = 01112
6 01102 14
j = 01112 + 00012 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 18+5

7 _ 01112 5 i = 7 = 01112
6 01102 14
j = 01112 + 00012 = 10002
_

5 _ 01012 3 = 8
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 8 = 10002
6 01102 14
j = 10002 + 10002 = 100002
_

5 _ 01012 3 = 16
4 _ 01002 12

3 _ 00112 -2 Ignore updating j if


index is out of bounds
2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 9 = 10012
6 01102 14
j = 10012 + 00012 = 10102
_

5 _ 01012 3 = 10
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 2+-9

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 9 = 10012
6 01102 14
j = 10012 + 00012 = 10102
_

5 _ 01012 3 = 10
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8
Linear Construction
11 _ 10112 4

10 _ 10102 -7

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 10 = 10102
6 01102 14
j = 10102 + 00102 = 11002
_

5 _ 01012 3 = 12
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -8+-7
Linear Construction
11 _ 10112 4

10 _ 10102 -7

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 10 = 10102
6 01102 14
j = 10102 + 00102 = 11002
_

5 _ 01012 3 = 12
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -15
Linear Construction
11 _ 10112 4

10 _ 10102 -7

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 11 = 10112
6 01102 14
j = 10112 + 00012 = 11002
_

5 _ 01012 3 = 12
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -15+4
Linear Construction
11 _ 10112 4

10 _ 10102 -7

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 11 = 10112
6 01102 14
j = 10112 + 00012 = 11002
_

5 _ 01012 3 = 12
4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
12 _ 11002 -11
Linear Construction
11 _ 10112 4

10 _ 10102 -7

9 _ 10012 -9

8 _ 10002 23

7 _ 01112 5 i = 12 = 11002
6 01102 14
j = 11002 + 01002 = 100002
_

5 _ 01012 3 = 16
4 _ 01002 12

3 _ 00112 -2 Ignore updating j if


index is out of bounds
2 _ 00102 7

1 _ 00012 3
12 _ 11002 -11
Linear Construction
11 _ 10112 4
Constructed Fenwick
10 10102 -7
tree! We can now
_

9 _ 10012 -9 perform point and


8 10002 23
range query updates as
required.
_

7 _ 01112 5

6 _ 01102 14

5 _ 01012 3

4 _ 01002 12

3 _ 00112 -2

2 _ 00102 7

1 _ 00012 3
Construction Algorithm
# Make sure values is 1-based!
function construct(values):

N := length(values)

# Clone the values array since we’re


# doing in place operations
tree = deepCopy(values)

for i = 1,2,3, … N:
j := i + LSB(i)
if j < N:
tree[j] = tree[j] + tree[i]

return tree
Fenwick Tree source code
follows in next video!

Implementation source code and tests can


all be found at the following link:
github.com/williamfiset/data-structures
Fenwick Tree
Source Code

William Fiset
Source Code Link
Implementation source code
and tests can all be found
at the following link:

github.com/williamfiset/data-structures

NOTE: Make sure you have understood the


previous video sections explaining how a
Fenwick Tree works before continuing!
Fenwick Tree
Range Update
Visualization
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 6
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 6 + -1
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 6 + -1 + -10
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 6 + -1 + -10 + 26
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 6 + -1 + -10 + 26
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (-11
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (-11 + 26)
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (-11 + 26)
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (-11 + 26) = 6
2 _ 00010 5
1 _ 00001 4
16 10000 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
N/A 4 1 -3 7 2 4 11 0 -5 -6 9 -8 2 -3 6 7
15 _ 01111 6
14 _ 01110 -1 0
13 _ 01101 2
12 _ 01100 -10
11 _ 01011 9 1 2 4 8 16
10 01010
_ -11
9 _ 01001 -5 3 5 6 9 10 12
8 _ 01000 26
7 11 13 14
7 _ 00111 11
6 _ 00110 6
15
5 _ 00101 2
4 _ 00100 9 Find the sum in the array between [11,15]
3 _ 00011 -3 (6 + -1 + -10 + 26) - (-11 + 26) = 6
2 _ 00010 5
1 _ 00001 4
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 _ 01001
8 _ 01000
7 _ 00111
6 _ 00110
5 _ 00101
4 _ 00100
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 _ 01001
8 _ 01000
7 _ 00111 Least significant bits
6 _ 00110
5 _ 00101
4 _ 00100
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 01001
In other words: Place an
_

8 01000
edge between nodes i and i
_

7 00111
_

without its LSB.


6 _ 00110
5 _ 00101
4 _ 00100
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 01001
In other words: Place an
_

8 01000
edge between nodes i and i
_

7 00111
_

without its LSB.


6 _ 00110
5 _ 00101 13
4 _ 00100 1101
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 01001
In other words: Place an
_

8 01000
edge between nodes i and i
_

7 00111
_

without its LSB.


6 _ 00110
5 _ 00101 13 -> 12
4 _ 00100 1101 -> 1100
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 01001
In other words: Place an
_

8 01000
edge between nodes i and i
_

7 00111
_

without its LSB.


6 _ 00110
5 _ 00101 13 -> 12 -> 8
4 _ 00100 1101 -> 1100 -> 1000
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Least Significant Bit
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100 Idea: Place an edge between values
11 01011 who only differ by their Least
Significant Bit (LSB) in binary.
_

10 _ 01010
9 01001
In other words: Place an
_

8 01000
edge between nodes i and i
_

7 00111
_

without its LSB.


6 _ 00110
5 _ 00101 13 -> 12 -> 8 -> 0
4 _ 00100 1101 -> 1100 -> 1000 -> 0000
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011
10 _ 01010
9 _ 01001
8 _ 01000
7 _ 00111
6 _ 00110
5 _ 00101
4 _ 00100
3 _ 00011
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 16
10 _ 01010
9 _ 01001
8 _ 01000
7 _ 00111
6 _ 00110
5 _ 00101
4 _ 00100
3 _ 00011 16 -> 0
2 00010
_

10000 -> 00000


1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 16
10 _ 01010
9 _ 01001
8 _ 01000
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
15
_

3 _ 00011
2 _ 00010 1111
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 16
10 _ 01010
9 _ 01001
8 _ 01000
14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
15 -> 14
_

3 _ 00011
2 _ 00010 1111 -> 1110
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 16
10 _ 01010
9 _ 01001 12
8 _ 01000
14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
15 -> 14 -> 12
_

3 _ 00011
2 _ 00010 1111 -> 1110 -> 1100
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 12
8 _ 01000
14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
15 -> 14 -> 12 -> 8
_

3 _ 00011
2 _ 00010 1111 -> 1110 -> 1100 -> 1000
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 12
8 _ 01000
14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
15 -> 14 -> 12 -> 8 -> 0
_

3 _ 00011
2 _ 00010 1111 -> 1110 -> 1100 -> 1000 -> 0000
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 12
8 _ 01000
13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011 13 -> 12
2 _ 00010 1101 -> 1100
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 12
8 _ 01000
11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011 11
2 _ 00010 1011
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 10 12
8 _ 01000
11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011 11 -> 10
2 _ 00010 1011 -> 1010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 10 12
8 _ 01000
11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011 11 -> 10 -> 8
2 _ 00010 1011 -> 1010 -> 1000
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 9 10 12
8 _ 01000
11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011 9 -> 8
1001 -> 1000
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
7
_

3 00011
0111
_

2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 8 16
10 _ 01010
9 _ 01001 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
7 -> 6
_

3 00011
0111 -> 0110
_

2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 4 8 16
10 _ 01010
9 _ 01001 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
7 -> 6 -> 4
_

3 00011
0111 -> 0110 -> 0100
_

2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 4 8 16
10 _ 01010
9 _ 01001 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
7 -> 6 -> 4 -> 0
_

3 00011
0111 -> 0110 -> 0100 -> 0000
_

2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 4 8 16
10 _ 01010
9 _ 01001 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 00100
_

5 -> 4
3 00011
0101 -> 0100
_

2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 4 8 16
10 _ 01010
9 _ 01001 3 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100 3
3 _ 00011 0011
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 2 4 8 16
10 _ 01010
9 _ 01001 3 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100 3 -> 2
3 _ 00011 0011 -> 0010
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 2 4 8 16
10 _ 01010
9 _ 01001 3 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100 3 -> 2 -> 0
3 _ 00011 0011 -> 0010 -> 0000
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 1 2 4 8 16
10 _ 01010
9 _ 01001 3 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100 1 -> 0
3 _ 00011 0001 -> 0000
2 _ 00010
1 _ 00001
16 10000
Fenwick Tree Visualization
15 _ 01111
14 _ 01110 0
13 _ 01101
12 _ 01100
11 _ 01011 1 2 4 8 16
10 _ 01010
9 _ 01001 3 5 6 9 10 12
8 _ 01000
7 11 13 14
7 _ 00111
6 _ 00110
15
5 _ 00101
4 _ 00100
3 _ 00011
2 _ 00010
1 _ 00001
Fenwick Tree Analysis

Although the values contained by


different Fenwick trees may differ, the
actual structure of the tree does not
depend on the values it is holding.
Fenwick Tree Analysis
The furthest node from the root will
always be at most log2(n) nodes deep.
This happens when all the trailing bits
are 1’s. These numbers are of the form
2n-1.

21-1 = 1 = 0b000001
22-1 = 3 = 0b000011
23-1 = 7 = 0b000111
4
2 -1 = 15 = 0b001111
25-1 = 31 = 0b011111
26-1 = 63 = 0b111111
Fenwick Tree Analysis
Odd nodes are always leaves in our Fenwick Tree
because their LSB is always a 1.

1 2 4 8 16

3 5 6 9 10 12

7 11 13 14

15

You might also like