Реализация запроса в дереве отрезков сверху — различия между версиями
Shagal (обсуждение | вклад) (→Реализация) |
Shagal (обсуждение | вклад) (→Пример) |
||
Строка 25: | Строка 25: | ||
[[Файл:Шагал1538.JPG|right|380px|thumb|Дерево отрезков]] | [[Файл:Шагал1538.JPG|right|380px|thumb|Дерево отрезков]] | ||
− | Рассмотрим работу программы на дереве отрезков для элементов [1 .. 8]. | + | Рассмотрим работу программы на дереве отрезков для элементов <tex>[1 .. 8]</tex>. |
− | Пусть запрашиваемая сумма - это отрезок [2 .. 5]. | + | Пусть запрашиваемая сумма - это отрезок <tex>[2 .. 5]</tex>. |
− | *Текущий отрезок [1 .. 8], он больше [2 .. 5] => переходим по рекурсивным вызовам на [1 .. 4] и [5 .. 8] | + | *Текущий отрезок <tex>[1 .. 8]</tex>, он больше <tex>[2 .. 5]</tex> => переходим по рекурсивным вызовам на <tex>[1 .. 4]</tex> и <tex>[5 .. 8]</tex> |
− | *[1 .. 4] выходит за границы [2 .. 5], [5 .. 8] выходит за границы [2 .. 5] => переходим по рекурсивным вызовам на [1 .. 2], [3 .. 4] и [5 .. 6], [7 .. 8]. | + | *<tex>[1 .. 4]</tex> выходит за границы<tex> [2 .. 5]</tex>, <tex>[5 .. 8]</tex> выходит за границы <tex>[2 .. 5]</tex> => переходим по рекурсивным вызовам на <tex>[1 .. 2]</tex>, <tex>[3 .. 4]</tex> и <tex>[5 .. 6]</tex>, <tex>[7 .. 8]</tex>. |
− | *[1 .. 2] выходит за границы [2 .. 5] => переходим в листья 1, 2; [3 .. 4] целиком внутри [2 .. 5] => возвращаем значение в [3 .. 4]; | + | *<tex>[1 .. 2]</tex> выходит за границы <tex>[2 .. 5]</tex> => переходим в листья 1, 2; <tex>[3 .. 4]</tex> целиком внутри <tex>[2 .. 5]</tex> => возвращаем значение в <tex>[3 .. 4]</tex>; |
− | [7 .. 8] не пересекается с [2 .. 5] => возвращаем нулевое значение, [5 .. 6] выходит за границы [2 .. 5] => переходим к листьям 5 и 6 | + | <tex>[7 .. 8]</tex> не пересекается с <tex>[2 .. 5]</tex> => возвращаем нулевое значение, <tex>[5 .. 6]</tex> выходит за границы <tex>[2 .. 5]</tex> => переходим к листьям 5 и 6 |
− | *лист 6 не пересекается с отрезком [2 .. 5] => возвращаем нулевое значение, лист 5 целиков внутри [2 .. 5] => возвращаем значение в листе 5. | + | *лист 6 не пересекается с отрезком <tex>[2 .. 5]</tex> => возвращаем нулевое значение, лист 5 целиков внутри <tex>[2 .. 5]</tex> => возвращаем значение в листе 5. |
==Реализация== | ==Реализация== |
Версия 23:30, 16 мая 2011
Содержание
Алгоритм
Будем рассматривать запрос на примере задачи RSQ(запрос суммы)
Пусть есть дерево отрезков и задача найти сумму на отрезке [a .. b], далее искомый.
Запустим рекурсивную процедуру от всего отрезка.
Проверять будем два условия :
- если текущий отрезок не пересекается с искомым, то возвращаем нулевое значение.
Например:
текущий [1..2], а искомый [3 .. 4];
- текущий отрезок целиком внутри, то возвращаем значение в вершине.
Например:
текущий [2..3], а искомый [1 .. 4];
Далее переходим к рекурсивным вызовам результат функции от текущего отрезка и искомого = сумма результатов от детей текущего отрезка и искомого.
Пример
Рассмотрим работу программы на дереве отрезков для элементов
. Пусть запрашиваемая сумма - это отрезок .- Текущий отрезок , он больше => переходим по рекурсивным вызовам на и
- выходит за границы , выходит за границы => переходим по рекурсивным вызовам на , и , .
- выходит за границы => переходим в листья 1, 2; целиком внутри => возвращаем значение в ;
не пересекается с => возвращаем нулевое значение, выходит за границы => переходим к листьям 5 и 6
- лист 6 не пересекается с отрезком => возвращаем нулевое значение, лист 5 целиков внутри => возвращаем значение в листе 5.
Реализация
int sum (int v, int tl, int tr, int l, int r) { if ([l,r][tl, tr]) = return 0; if ([l,r] [tl, tr]) return t[v]; int tm = (tl + tr) / 2; return sum (v*2, tl, tm, l, min(r,tm)) + sum (v*2+1, tm+1, tr, max(l,tm+1), r); }