3.4.16 · HinglishTrees

Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

1,866 words8 min readRead in English

3.4.16 · Coding › Trees


WHY yeh structure exist karta hai?


WHAT har cell mein stored hai? (lowbit insight)

Values ke ek array ke liye (1-indexed), Fenwick cell define karo

jahan ==== ke lowest set bit ki value hai.

Toh cell index par khatam hone wale elements ka sum store karta hai.

binary lowbit cover karta hai ke liye
1 0001 1 [1,1]
2 0010 2 [1,2]
3 0011 1 [3,3]
4 0100 4 [1,4]
5 0101 1 [5,5]
6 0110 2 [5,6]
7 0111 1 [7,7]
8 1000 8 [1,8]
Figure — Fenwick tree (Binary Indexed Tree) — prefix sums, O(log n) update and query

HOW: query ko scratch se derive karna

Hum chahte hain .

Step 1. Cell humein already last block deta hai: . Kyun? Yeh literally iska definition hai.

Step 2. Jo bacha hai woh hai — us block se pehle wala part. Kyun? Lowbit-sized chunk hataane ke baad humein ek chhote index tak prefix chahiye hoti hai.

Step 3. Recurse karo: add karte raho aur lowest bit strip karte raho jab tak na ho jaye. Yeh jaldi terminate kyun hota hai? Har step se ek set bit remove karta hai, toh yeh zyada se zyada (set bits ki sankhya) baar run karta hai.

def query(tree, i):          # prefix sum a[1..i]
    s = 0
    while i > 0:
        s += tree[i]
        i -= i & (-i)        # strip lowest set bit
    return s

HOW: update ko scratch se derive karna

mein add karne ke liye har us cell ko fix karna hoga jiske block mein index hai.

Step 1. Cell mein hai (uska block par khatam hota hai). Wahaan add karo. Step 2. Agla cell jo contain karta hai woh index par hai. Kyun? Agla bada block jo ko include karta hai usi left edge se start hota hai lekin aage tak extend karta hai; uska index plus uska apna lowbit hai, jo in blocks ki nesting structure ke according ke barabar hai. Step 3. Repeat karo jabtak .

def update(tree, n, j, delta):   # a[j] += delta
    while j <= n:
        tree[j] += delta
        j += j & (-j)            # go to next responsible cell

Range sum sirf hai.


Worked examples


Common mistakes


Complexity

Linear build (80/20 trick): tree[i] = a[i] initialize karo, phir ke liye 1 se tak, apna block sum apne parent mein push karo: if i+lowbit(i) <= n: tree[i+lowbit(i)] += tree[i]. Kyun? Har cell pehle complete hoti hai, phir apna block agla responsible cell ko donate karti hai — ek pass, .


Fenwick cell tree[i] kya store karta hai?
a[i-lowbit(i)+1 .. i] ka sum, length lowbit(i) ka ek block jo i par khatam hota hai.
lowbit(i) kaise compute karte hain?
i & (-i), lowest set bit ki value (two's-complement negation use karta hai).
Query (prefix sum) loop direction?
tree[i] add karo, phir i -= i & (-i), jab tak i == 0 (NEECHE jaao).
Update (point add) loop direction?
tree[j] mein delta add karo, phir j += j & (-j), jabtak j <= n (UPAR jaao).
Update aur query ki time complexity?
Dono , kyunki har step index ka ek bit change karta hai.
Range sum [l, r] kaise milega?
query(r) - query(l-1).
Fenwick tree 1-indexed kyun honi chahiye?
lowbit(0)=0, toh index 0 par loops kabhi progress nahi karte; index 0 ka koi lowest set bit nahi hai.
Kisi given element index j ko kitni cells contain karti hain?
— chain j, j+lowbit(j), ... n tak.
O(n) build trick kya hai?
tree[i]=a[i]; phir har i ke liye, if i+lowbit(i)<=n: tree[i+lowbit(i)] += tree[i].
Plain prefix-sum array ki weakness jo Fenwick fix karta hai?
per update; Fenwick update ko karta hai fast queries rakhte hue.

Recall Feynman: ek 12-saal ke bachche ko explain karo

Socho ek row mein numbered boxes hain. Har box se ek-ek karke total maangne ki jagah (slow), kuch special boxes apne pehle wale boxes ke ek chunk ka running subtotal rakhte hain. Chunk size ek number trick se decide hoti hai: box ke number ko binary mein likhkar sabse daayein wali 1 dekho — woh batata hai woh box kitne boxes summarize karta hai. "Box 6 tak total" paane ke liye, tum sirf do-teen subtotal boxes visit karte ho aur unhe add karte ho — jaise ek-ek candy ginne ki jagah do pre-packed bundles utha lena. Ek candy count change karne ke liye, tum sirf un thodi bundles fix karte ho jo use contain karti hain. Dono taraf: sirf muthi bhar steps, kabhi poori row nahi.

Connections

  • Prefix sum array-query, -update baseline jo Fenwick improve karta hai.
  • Segment tree — zyada general (koi bhi associative op, range updates), lekin heavy; Fenwick sums ke liye lean special case hai.
  • Two's complement representation — isliye i & -i lowest set bit isolate karta hai.
  • Binary representation of integers — set bits = query/update steps ki sankhya.
  • Inversion counting / Order statistics — classic Fenwick applications.
  • Range update with difference array — range-update/point-query ke liye BIT ke saath combine karo.

Concept Map

slow prefix O of n

slow update O of n

motivates

stores in each cell

sets block length

lowest set bit

assembled by

repeatedly

until i=0

affected cells

add delta then

until i greater than n

O of log n

O of log n

Plain array

Need both fast

Prefix-sum array

Fenwick tree

tree i = sum of block ending at i

lowbit i = i AND -i

Strip lowest bit

Prefix query

Point update

Add lowest bit

Both fast