Дан массив: нужно отвечать на суммы на отрезке a[l:r] и менять отдельные элементы a[i] = v. Когда и того и другого сотни тысяч, не годятся ни наивный цикл (O(n) на запрос), ни префиксные суммы (запрос O(1), но обновление O(n)). Дерево отрезков и дерево Фенвика делают обе операции за O(log n).

![Дерево сумм для [5 2 7 1 4 3 6 8]: запрос [2, 6) берёт два готовых узла, 8 и 7](img/lessons/algorithms/segment-fenwick-trees-segment.svg)

Цена простых методов

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
ПодходЗапросОбновлениеПостроение
наивная суммаO(n)O(1)O(1)
префиксные суммыO(1)O(n)O(n)
дерево отрезковO(log n)O(log n)O(n)
дерево ФенвикаO(log n)O(log n)O(n log n)

Дерево отрезков