Сканер силы на арене

тема: Fenwick/Segment tree · уровень: продвинутый

Условие

В игре есть длинная арена из N клеток. В каждой клетке стоит энергетический тотем с силой A[i].

Во время матча ведущий делает запросы двух типов:

Тебе нужно быстро отвечать на все запросы.

Формат ввода

Первая строка: два целых числа N и Q — число клеток и число запросов. Вторая строка: N целых чисел A[1], A[2], ..., A[N]. Далее Q строк, каждая — один запрос:

Формат вывода

Для каждого запроса вида Q l r выведи одно число — максимум на отрезке.

Ограничения

Пример

Ввод:

5 7
1 3 -2 7 4
Q 2 5
U 3 10
Q 1 3
Q 3 3
U 5 -5
Q 4 5
Q 1 5

Вывод:

7
10
10
7
10

Как решать — идея подхода

Приём: Дерево отрезков для максимума

Ключевое наблюдение: после изменения A[i] пересчитывать максимум на каждом запросе простым проходом по отрезку нельзя — в худшем случае это O(N) на запрос. При 65000 запросах получится слишком много операций.

Нужно дерево отрезков. Это двоичное дерево, где каждая вершина отвечает за некоторый непрерывный кусок массива и хранит максимум на нём. Лист хранит одно значение A[i], а его родитель — max(левый_сын, правый_сын). Значит, если меняется один элемент, затронуты только его лист и вершины на пути к корню.

Каждая операция проходит лишь по высоте дерева, поэтому построение занимает O(N), а один запрос или обновление — O(log N).

Грабли: в вводе индексы начинаются с 1, а массивы Python — с 0. Также обычное дерево Фенвика для максимумов здесь неудобно: значение разрешено не только увеличивать, но и уменьшать, а максимум после уменьшения нельзя быстро «вычесть» из накопленных данных.

Решить задачу с автопроверкой на Python →

Куда дальше