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

Дерево отрезков: сумма на отрезке и обновление точки за O(log n).

Префиксные суммы отвечают на «сумму на отрезке» за O(1), но ломаются, как только массив начинает МЕНЯТЬСЯ: одно обновление — пересчёт всех префиксов. Дерево отрезков делает и запрос, и обновление за O(log n). Идея: над массивом строится двоичное дерево; каждая вершина хранит сумму своего отрезка. Корень — сумма всего массива, листья — отдельные элементы. • обновление элемента затрагивает только вершины на пути от листа к корню — их O(log n); • запрос [l, r] разбивается на O(log n) готовых отрезков дерева.

Введите: 5 3, массив 1 2 3 4 5, затем: sum 2 4 / set 3 10 / sum 2 4

Запустите пример: сумма [2,4] сначала 9, после set 3 10 становится 16. Как читать код: • вершина v отвечает за отрезок [tl, tr]; дети — половины отрезка, номера 2v и 2v+1; • массив tree размером 4n гарантированно вмещает всё дерево; • query возвращает 0 для непересекающихся отрезков — ноль нейтрален для суммы. Дерево отрезков — конструктор: замените + на min или max (и нейтральный элемент на бесконечность) — получите запросы минимума/максимума. Продвинутая версия с «ленивыми» обновлениями умеет менять целые отрезки за O(log n) — изучите её, когда встретите такую задачу.
Задание: переделайте дерево на МАКСИМУМ на отрезке (три правки: операция, нейтральный элемент, вывод) и проверьте на своём примере. Отметьте урок пройденным.
Доска