Изменения

Перейти к: навигация, поиск

Реализация запроса в дереве отрезков сверху

299 байт добавлено, 22:14, 5 сентября 2019
Лишний пробел
Используем в алгоритме не отрезки, а полуинтервалы (левая граница включительно, а правая {{---}} нет).
Пусть есть уже [[Дерево отрезков. Построение|построенное дерево отрезков]] и идет запрос на полуинтервале <tex>[a .. \ldots b)</tex>.
В качестве параметров рекурсий передаем следующие переменные:
Запустим рекурсивную процедуру от всего полуинтервала (то есть от корневой вершины).
Для текущего состояния проверяем следующие условия :
* Если текущий полуинтервал не пересекается с искомым, то возвращаем нейтральный элемент.
:''Например'': текущий <tex>[1..\ldots 3)</tex>, а искомый <tex>[3 .. \ldots 5)</tex>;
* Если текущий полуинтервал лежит внутри запрашиваемого полуинтервала, то возвращаем значение в текущей вершине.
:''Например'': текущий <tex>[2..\ldots 3)</tex>, а искомый <tex>[2..\ldots 4)</tex>;
* Иначе переходим к рекурсивным вызовам функций от детей вершины. При этом возвращаем значение на текущем полуинтервале, как функцию (соответствующую типу нашего запроса) от результатов выполнения на детях.
==Пример==
Рассмотрим данный алгоритм на примере задачи <tex>\mathrm{RSQ }</tex> (Range Sum Query {{---}} запрос суммы на отрезке).
При этом сумма на текущем полуинтервале (в случае вызова рекурсий от детей) равна сумме результатов выполнения операции на этих детях.
Пусть дерево содержит <tex>8</tex> листьев и запрашиваемая сумма
{{---}} это отрезок <tex>[1 .. \ldots 4]</tex> (полуинтервал <tex>[1 .. \ldots 5)</tex>).
[[Файл:Image_4.png|right|602px|Пример рабoты алгоритма]]
Рассмотрим данный алгоритм на определенных глубинах рекурсии (, то есть на разных уровнях дерева(на рисунке глубина обозначена слева от уровня):
* На глубине <tex>0</tex>. (на рисунке глубина обозначена слева от уровня). ** Текущий полуинтервал <tex>[0 .. \ldots 8)</tex> пересекается с <tex>[1 .. \ldots 5) \Rightarrow</tex> рекурсивно переходим по рекурсивным вызовам на к <tex>[0 .. \ldots 4)</tex> и <tex>[4 .. \ldots 8)</tex>
 * На глубине <tex>1</tex>. ** <tex>[0 .. \ldots 4)</tex> и <tex>[4 .. \ldots 8)</tex> пересекаются с <tex> [1 .. \ldots 5) \Rightarrow </tex> переходим по рекурсивным вызовам на полуинтервалах <tex>[0 ..\ldots 2)</tex>, <tex>[2 .. \ldots 4)</tex>, <tex>[4 .. \ldots 6)</tex> и <tex>[6 .. \ldots 8)</tex> 
* На глубине <tex>2</tex>.
** <tex>[0 .. \ldots 2)</tex> и <tex>[4 .. \ldots 6)</tex> пересекаются с <tex>[1 .. \ldots 5) \Rightarrow </tex> переходим в листья <tex>[0\ldots 1), [1\ldots 2), [4\ldots 5), [5 \ldots 6) </tex>** <tex>[2 .. \ldots 4) </tex> полностью лежит внутри <tex>[1 .. \ldots 5) \Rightarrow </tex> возвращаем сумму на этом отрезке** <tex>[6 .. \ldots 8)</tex> не пересекается с <tex>[1 .. \ldots 5) \Rightarrow </tex> возвращаем нулевое значение 
* На глубине <tex>3</tex>.
** Листья <tex>[1\ldots 2), [4\ldots 5)</tex> лежат в запрашиваемом интервале <tex>\Rightarrow </tex> возвращаем значения в них** Листья <tex>[0\ldots 1), [5\ldots 6)</tex> лежат вне <tex>[1 .. \ldots 5) \Rightarrow </tex> возвращаем нулевое нейтральное значение
Таким образом ответ на полуинтервале <tex>[1 .. \ldots 5)</tex> равен сумме значений в вершинах, отвечающих за полуинтервалы <tex>[1 .. \ldots 2)</tex>, <tex>[2 .. \ldots 4)</tex> и <tex>[4 .. \ldots 5)</tex>.
==Реализация==
Пусть в узлах дерева хранятся структуры из трех полей:
* <tex>\mathtt{left}</tex> {{---}} левая граница полуинтервала, за который "отвечает" текущая вершина.* <tex>\mathtt{right}</tex> {{---}} правая граница этого полуинтервала.* <tex> \mathtt{res}</tex> {{---}} результат операции на полуинтервале.* <tex>\varepsilon</tex> {{---}} нейтральный для данной операции элемент.
'''int''' query('''int''' node, '''int''' a, '''int''' b)
r = tree[node].right
'''if''' [l, r) <tex>\cap </tex> [a, b) == <tex>\varnothing</tex>
'''return''' ''<tex>\varepsilon</tex>'' <span style="color:#008000">// <tex>\varepsilon</tex> {{---}} нейтральный для данной операции элемент</span>
'''if''' [l, r) <tex>\subset</tex> [a, b)
'''return''' tree[node].res
Анонимный участник

Навигация