A Fenwick tree is a 1-indexed array t[1..n] where cell j stores the sum of the original values at positions j - lowbit(j) + 1 .. j, and lowbit(j) = j & -j is the value of the lowest set bit of j. Both operations are just walks over indexes. Write those walks, returning the indexes instead of doing any sums:
lowbit(i) -> int: the lowest set bit ofi(fori >= 1).update_indexes(i, n) -> list[int]: the cells, in visiting order, thatadd(i, delta)changes: start ati, then repeatedly addlowbit, while the index is<= n. These are exactly the cells whose range contains positioni.query_indexes(i) -> list[int]: the cells, in visiting order, thatprefix_sum(i)reads: start ati, then repeatedly subtractlowbit, while the index is> 0. Their ranges fit together to cover1..iexactly once.query_indexes(0)is[].
lowbit(12) # 4 (12 = 0b1100)
update_indexes(5, 16) # [5, 6, 8, 16]
query_indexes(13) # [13, 12, 8] ranges 13..13, 9..12, 1..8
Constraints: 1 <= i <= n for update_indexes, 0 <= i for query_indexes.
Show hint
i & -i isolates the lowest set bit; updates climb with i += i & -i, prefix queries descend with i -= i & -i, so both take O(log n) steps.