0% found this document useful (0 votes)
23 views27 pages

Shubham

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views27 pages

Shubham

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 27

Data Structures

Binary Indexed Trees


TH I N K F A ST

Mostafa Saad Ibrahim


PhD Student @ Simon Fraser University
Contents:-

◼Background
◼Problem Statement
◼Motivation
◼Prefix Sum
◼Upadation
◼References
Problem Statement

◼ We often need some sort of data structure to make our


algorithms faster. The Binary Indexed Trees structure,
proposed by Peter M. Fenwick. This structure was first used
for data compression, Peter M. Fenwick. We begin by
motivating the use of this structure by an example.

◼ Consider the following problem: There are n boxes that


undergo the following queries:
1. add marble to box i
2. sum marbles from box k to box l

◼ Our goal is to implement those two queries.


Problem Statement

 The naive solution has time complexity of O(1) for query 1


and O(n) for query 2.

 Suppose we make m queries. The worst case (when all the


queries are 2) has time complexity O(n * m).

 Using some data structure (i.e. RMQ) we can solve this


problem with the worst case time complexity of O(mlogn)

 Binary Indexed Tree data structure, also with the worst time
complexity O(m log n) — but Binary Indexed Trees are
easier to code and require less memory space than RMQ.
Binary Representation
Removing bits from mask
 mask = think in integer bits
 Assume we have numbers X, Y
 If for every position in Y with 1 AND X has 1
 X = 10010100
 Y = 00010100
 X - Y removes all Y 1s from X
 Another longer/general way to do so:
 X & ~Y
 10010100 &
 11101011 =
 10000000
Least/Most Significant Bit

Src: http://www.electronique-et-informatique.fr/Digit/images/MSBLSB.gif
Src: http://tronixstuff.com/wp-content/uploads/2011/05/binnum.jpg
Two’s Complement Representation

 Start to flip AFTER the “last bit”


 -number = 2’s complement of number
 One way to compute manually:

 Get 1’s complement...then add 1


Removing Last Bit
 Get last bit using index & -index

 +20 = 00010100
 -20 = 11101100
 20 & -20 = 00000100

 Remove last bit

 Get it...subtract it
 index - (index & -index)
 00010100 - 00000100 = 00010000
Integer as sums of powers of 2

= 010010011

Src: http://images.slideplayer.com/5/1546412/slides/slide_22.jpg
Our problem
 Let’s move to our problem
 Given an array of integer N
 Assume index 0 always will be 0 (NOT in use)

 2 query types:
 Add value val to position index
 Sum values from 1 to index

 Segment Tree can be used to such problem


 O(N) preprocess, O(NlogN) queries, O(nlogn) memory

 BIT has a better memory order (shorter code)


 O(n) memory + O(NlogN) queries
Problem Example
0 1 2 3 4 5 6 7 8 9 10 11

xx 3 2 -1 6 5 4 -3 3 7 2 3

- Accumulative Sum (1, 3): 3 + 2 - 1 = 4


- Accumulative Sum (1, 5): 3 + 2 - 1 + 6 + 5 = 15
- Add: index 3, value = 4

xx 3 2 4 6 5 4 -3 3 7 2 3

- AccumulativeSum (1, 3): 3 + 2 + 4 = 9


- Accumulative Sum (1, 5): 3 + 2 + 4 + 6 + 5 = 21
Motivation
 Integer = Sum of Powers of 2
 Accumulative Sum = Sum of Sub sums
 Recall: 147 = 128 + 16 + 2 + 1
 Think in accumulative sum (1 to 147)
 Sum of last 1 number +
 Sum of next 2 numbers +
 Sum of next 16 numbers +
 Sum of next 128 numbers

 Sum(1,147) =
 Sum(147,147) + Sum(146,145) + Sum(144,129) + Sum(128,1)
 147 ⇒ positions {147, 146, 144, 128} with ranges {1, 2, 16,
128}
Motivation

◼ To get starting positions fast? Remove last bit

▪ 147 = 010010011 [remove last 1 bit]


▪ 146 = 010010010 [remove last 1 bit]
▪ 144 = 010010000 [remove last 1 bit]
▪ 128 = 010000000 [remove last 1 bit]
▪ 0 = DONE
◼ How to interpret:
▪ 147 responsible for range 147 to > 146
▪ 146 responsible for range 146 to > 144
▪ 144 responsible for range 144 to > 128
▪ 146 responsible for range 128 to > 0
Binary Indexed Tree
 Create a new array of Length N, name it BIT
 BIT[position] = sum of its responsible range
 Then For each Query

 Sum(147)= BIT(147) + BIT(146) + BIT(144) + BIT(128)


 That is: 4 steps only to get the answer
 Sum(144) = BIT(144) + BIT(128)
 Sum(15) = BIT(15) + BIT(14) + BIT(12) + BIT(8)
 Recall: 1111 = 1111, 1110, 1100, 1000, 0
 Sum(11) = BIT(11) + BIT(10) + BIT(8)
 Recall 1011: 1011, 1010, 1000, 0
 Sum(7) = BIT(7) + BIT(6) + BIT(4) ⇒ 111, 110, 100, 0
Binary Indexed Tree

Sum(15) = BIT(15) + BIT(14) + BIT(12) + BIT(8)

E.g. node 12 has values: BIT[12] = val[12] + val[11]+val[9]


12 = 1100 ⇒ removing last 1 bit ⇒ 1000 = 8
Then parent of 12 ⇒ 8 (e.g. next closest position 12 is not covering)
Notice: we removed bit at position 2 ⇒ 12 covers 2^2 numbers = 12 - 8 = 4
Binary Indexed Tree

Notice: 8 = 1000 => has 3 trailing zeros. Try to replace each 0 with 1
1001 = 9
1010 = 10
1100 = 12
# of trailing zeros = # children … child remove last bit => go to parent
Get Interval Accumulation
Sum(15) = BIT(15) + BIT(14) + BIT(12) + BIT(8)
= 1111 ⇒ 1110 ⇒ 1100 ⇒ 1000 ⇒ 0 = STOP

15 is responsible for 1 number, 14 for 2, 12 for 4, 8 for 8 numbers


Updating position

Position 1: Covered by 4 intervals ⇒ 1, 2, 4, 8


Add -3 to 1 ⇒ add -3 to these 4 intervals

Given index, how to get smallest position covering it?


E.g. 1 ⇒ 2 6 ⇒ 8 10 ⇒ 12 13 ⇒ 14
Then 1 goes to 2...2 goes to 4..4 goes to 8 [recursive]
Updating position

◼ Recall given number idx it covers 2^r values


▪ r is position of “last bit”
▪ It covers numbers from idx to idx – 2^r + 1

◼ All following numbers cover 8 values

▪ 0001000 ⇒ r = 3 ⇒ 2^3 = 8
▪ 0101000
▪ 1101000
▪ 1111000
▪ 1001000
◼ So our focus on “last bit”, NOT before that
Updating position

◼ 1000 covers 8 numbers

▪ 1000 - 000 = 1000


▪ 1000 - 001 = 0111
▪ 1000 - 010 = 0110
▪ 1000 - 011 = 0101
▪ 1000 - 100 = 0100
▪ 1000 - 101 = 0011
▪ 1000 - 110 = 0010
▪ 1000 - 111 = 0001

◼ Each of these 8 numbers covered by 1000


◼ But 1000 is NOT their smallest cover number
Updating position

◼ Let’s get who covers 4 = 0100

▪ 4 has “last bit” at k = 2


▪ When target number enumerate its 2^r, one contains 100
▪ So we need to go at least 1 bit higher than k
▪ E.g. re-set last bit k = 3 ⇒ 1000 ⇒ first one to cover 0100

◼ Let’s get who covers 5 = 0101


▪ k=0
▪ We need target number to include our 1 at k = 0
▪ The earlier one should exist in smallest coverer number
▪ So again, shift k = 0 1 step to be in its enumeration
▪ E.g. re-set last bit k = 1 ⇒ 110. Note, 1000 also cover 5
Updating position

◼ Let’s get who covers 3 = 0011

▪ “last bit” at k = 0
▪ We need enumeration includes whole 11
▪ So parent need to be a 1 before these 11
▪ E.g. ⇒ 0100

◼ So general rule
▪ 100100001000 100100011100
▪ 100100010000 100100100000

◼ How to get that number easily?


▪ Just add 2^k ⇒ if one or more bits ⇒ shifted
▪ E.g. 100100011100 + 000000000100 = 100100100000
Updating tree
Updating tree

Notice: 8 = 1000 => has 3 trailing zeros. Remove last bit, and add 1, 2, 3...trailing ones
0100 = 4
0110 = 6
0111 = 7
# of trailing zeros = # children
Updating tree

Building initial tree from input: just iterate on input


and add it to its position
References
 Article on Prefix Sums and Their Applications by Guy E.
Blelloch School of Computer Science
Carnegie Mellon University Pittsburgh, PA 15213-3890

 Efficient Range Minimum Queries using Binary Indexed


Trees :
Mircea Dima and Rodica Ceterchi
Olympiads in Informatics, 2015, Vol. 9, 39–44
DOI:http://dx.doi.org/10.15388/ioi.2015.04

You might also like