Step 1. Cell i humein already last block deta hai: ∑k=i−lowbit(i)+1iak.
Kyun? Yeh literally iska definition hai.
Step 2. Jo bacha hai woh hai prefix(i−lowbit(i)) — 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: tree[i] add karte raho aur lowest bit strip karte raho jab tak i=0 na ho jaye.
Yeh jaldi terminate kyun hota hai? Har step i se ek set bit remove karta hai, toh yeh zyada se zyada (set bits ki sankhya) ≤log2n baar run karta hai.
prefix(i)=∑tree[i],i←i−lowbit(i)until i=0
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
aj mein δ add karne ke liye har us cell ko fix karna hoga jiske block mein index j hai.
Step 1. Cell j mein aj hai (uska block j par khatam hota hai). Wahaan δ add karo.
Step 2. Agla cell jo j contain karta hai woh index j+lowbit(j) par hai.
Kyun? Agla bada block jo j ko include karta hai usi left edge se start hota hai lekin aage tak extend karta hai; uska index j plus uska apna lowbit hai, jo in blocks ki nesting structure ke according j+lowbit(j) ke barabar hai.
Step 3. Repeat karo jabtak j≤n.
update: tree[j]+=δ,j←j+lowbit(j)until j>n
def update(tree, n, j, delta): # a[j] += delta while j <= n: tree[j] += delta j += j & (-j) # go to next responsible cell
Linear build (80/20 trick):tree[i] = a[i] initialize karo, phir i ke liye 1 se n 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, O(n).
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 O(logn), 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?
O(logn) — 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?
O(n) per update; Fenwick update ko O(logn) 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.