Реализация запроса в дереве отрезков снизу — различия между версиями
Nastya (обсуждение | вклад) (→Псевдокод) |
Nastya (обсуждение | вклад) |
||
| Строка 38: | Строка 38: | ||
'''return''' leftRes <tex> \circ </tex> rightRes | '''return''' leftRes <tex> \circ </tex> rightRes | ||
| − | == | + | ==Источники информации== |
| − | [http://e-maxx.ru/algo/segment_tree MAXimal :: algo :: Дерево отрезков] | + | * [http://e-maxx.ru/algo/segment_tree MAXimal :: algo :: Дерево отрезков] |
| − | [http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2 Википедия {{---}} Дерево отрезков] | + | * [http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2 Википедия {{---}} Дерево отрезков] |
| − | [http://rain.ifmo.ru/cat/view.php/vis/trees/segment-2006 Визуализатор] | + | * [http://rain.ifmo.ru/cat/view.php/vis/trees/segment-2006 Визуализатор] |
| − | [http://rain.ifmo.ru/cat/view.php/vis/trees/segment-2006/algorithm Алгоритм] | + | * [http://rain.ifmo.ru/cat/view.php/vis/trees/segment-2006/algorithm Алгоритм] |
| + | |||
| + | ==См. также== | ||
| + | * [http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B0_%D0%B2_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%B5_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2_%D1%81%D0%B2%D0%B5%D1%80%D1%85%D1%83 Реализация запроса в дереве отрезков сверху] | ||
Версия 11:34, 13 июня 2014
Содержание
Алгоритм
Реализация запроса снизу вверх в дереве отрезков является, в отличие от реализации запроса сверху вниз, итеративным методом. Будем рассматривать абстрактную операцию, обладающую свойством ассоциативности, и обозначать ее .
Построим дерево отрезков и установим границы отрезка на соответствующие им листья. Будем действовать в 3 этапа:
- Если элемент, попавший на левую границу, является правым сыном, то запишем в результат значение, полученное после выполнения нашей операции над предыдущим результатом и значением этого элемента, а левую границу перемещаем на один элемент вправо. Аналогично с правой границей (является ли она левым сыном). Таким образом мы учтем вклад нужной нам вершины и избавимся от вклада ненужного нам поддерева.
- Устанавливаем границы отрезка на родительские элементы текущих границ. Это позволит узнать, входит ли полученный отрезок в искомый или нет. Повторяем этап 1, пока границы не пересекутся.
- Если после завершения цикла границы совпадут, значит полученный отрезок входит в искомый, и надо пересчитать результат.
| Реализация запроса снизу вверх | Ещё один пример |
|
|
|
|
|
|
|
|
Псевдокод
Пусть результат считаем на отрезке []. При этом значения и , передающиеся в функцию, должны указывать на листья дерева (необходимо увеличить значение на индекс массива, с которого начинаются листья). Переменные и будут собирать значения на отрезках, отделившихся соответственно слева или справа от рассматриваемого.
int query(left : int, right : int):
leftRes = neutral
rightRes = neutral
while left < right
if left mod 2 == 0
leftRes = leftRes data[left]
left = left div 2
if right mod 2 == 1
rightRes = data[right] rightRes
right = (right - 1) div 2
if left == right
leftRes = leftRes data[left]
return leftRes rightRes







