Дерево отрезков
Материал из Википедии — свободной энциклопедии
Дерево отрезков — структура данных позволяющая быстро изменять значения в массиве и находить некоторые функции от элементов массива.
[править] Дерево отрезков в памяти
Пусть наш массив a имеет n элементов: . Выберем k такое, что
. Тогда для хранения дерева отрезков понадобиться массив b из 2k + 1 элементов. В ячейке b[2l + u] при u < 2k будет храниться число
, где f — функция, которую мы хотим вычислять от отрезков массива. Наиболее часто в качестве f берутся функции суммы, произведения, минимума и максимума.
[править] Изменение элемента
Пусть мы изменили значение a[i]. Тогда нам нужно присвоить элементу b[2k + i] значение f(a[i]). После чего нужно обновить значения b[2k − 1 + i / 2], b[2k − 2 + i / 4] и.т.д. Таким образом на добавление элемента уйдет O(k) = O(log(n)) действий.
[править] Подсчет функции для отрезка
Для подсчета функции от элементов используется следующая рекурсиваная процедура count от аргументов v,L,R,l,r. Здесь v — элемент массива b в котором находится значение функции для отрезка [L;R), а
— отрезок, на котором мы хотим посчитать функцию. Если L = l и R = r, то ответ равен b[v]. Если
, то ответ равен count(2v,L,(L + R) / 2,l,r). Если
, то ответ равен count(2v + 1,(L + R) / 2,R,l,r). Иначе отрезок [l,r) можно разбить на два отрезка: [l,(L + R) / 2) и [(L + R) / 2,r). Тогда ответом будет f(count(2v,L,(L + R) / 2,l,(L + R) / 2),count(2v + 1,(L + R) / 2,R,(L + R) / 2,r)). Таким образом, вычисление функции на отрезке [l,r) сводится к вычислению функции от O(log(n)) элементов массива b, которые соотвествуют некоторым отрезкам [2lu;2l(u + 1)).