The short way to write a segment tree is a flat list tree of length 2n:
- the leaves are
tree[n .. 2n-1], a copy ofnums; - every internal node
i(fromn - 1down to1) storestree[2i] + tree[2i + 1], the sum of its two children; tree[0]is unused and stays0.tree[1]ends up holding the sum of everything.
Write the two operations everything else is built on:
build(nums) -> list[int]: return that list of length2 * len(nums).update(tree, i, value) -> None: set positioni(0-based) of the original array tovalue, in place, and fix every ancestor so the invariant holds again. Only touch the O(log n) nodes on the way up; don't rebuild.
tree = build([5, 3, 2, 7])
# [0, 17, 8, 9, 5, 3, 2, 7]
# ^root ^ ^ leaves...
update(tree, 1, 10)
# tree == [0, 24, 15, 9, 5, 10, 2, 7]
Constraints: 1 <= len(nums) <= 10**5, values may be negative. n doesn't have to be a power of two; the same formulas still work.
Show hint
node i's parent is i // 2, so after writing the leaf at n + i, walk i //= 2 up to the root, recomputing each node from its two children.