Дерево отрезков
Дерево отрезков: сумма на отрезке и обновление точки за 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) — изучите её, когда встретите такую задачу.
Задание: переделайте дерево на МАКСИМУМ на отрезке (три правки: операция, нейтральный элемент, вывод) и проверьте на своём примере.
Отметьте урок пройденным.