Given an array, we must answer sums on a range a[l:r] and change single elements a[i] = v. If there are hundreds of thousands of both, neither the naive loop (O(n) per query) nor prefix sums (O(1) per query but O(n) per update) is good enough. A segment tree and a Fenwick tree make both operations O(log n).

![A sum tree for [5 2 7 1 4 3 6 8]: the query [2, 6) takes two ready nodes, 8 and 7](img/lessons/algorithms/segment-fenwick-trees-segment.svg)

The price of the simple methods

python
import math

n = 100_000                       # array size
q = u = 100_000                   # queries and updates
print("naive sums:      ", q * n)
print("prefix sums:     ", u * n)
print("segment tree:    ", (q + u) * math.ceil(math.log2(n)))
text
naive sums:       10000000000
prefix sums:      10000000000
segment tree:     3400000
ApproachQueryUpdateBuild
naive sumO(n)O(1)O(1)
prefix sumsO(1)O(n)O(n)
segment treeO(log n)O(log n)O(n)
Fenwick treeO(log n)O(log n)O(n log n)

The segment tree