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

Материал из Викиконспекты
Перейти к: навигация, поиск
(Реализация)
(Пример)
Строка 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];

Далее переходим к рекурсивным вызовам результат функции от текущего отрезка и искомого = сумма результатов от детей текущего отрезка и искомого.

Пример

Дерево отрезков

Рассмотрим работу программы на дереве отрезков для элементов [math][1 .. 8][/math]. Пусть запрашиваемая сумма - это отрезок [math][2 .. 5][/math].

  • Текущий отрезок [math][1 .. 8][/math], он больше [math][2 .. 5][/math] => переходим по рекурсивным вызовам на [math][1 .. 4][/math] и [math][5 .. 8][/math]


  • [math][1 .. 4][/math] выходит за границы[math] [2 .. 5][/math], [math][5 .. 8][/math] выходит за границы [math][2 .. 5][/math] => переходим по рекурсивным вызовам на [math][1 .. 2][/math], [math][3 .. 4][/math] и [math][5 .. 6][/math], [math][7 .. 8][/math].


  • [math][1 .. 2][/math] выходит за границы [math][2 .. 5][/math] => переходим в листья 1, 2; [math][3 .. 4][/math] целиком внутри [math][2 .. 5][/math] => возвращаем значение в [math][3 .. 4][/math];

[math][7 .. 8][/math] не пересекается с [math][2 .. 5][/math] => возвращаем нулевое значение, [math][5 .. 6][/math] выходит за границы [math][2 .. 5][/math] => переходим к листьям 5 и 6


  • лист 6 не пересекается с отрезком [math][2 .. 5][/math] => возвращаем нулевое значение, лист 5 целиков внутри [math][2 .. 5][/math] => возвращаем значение в листе 5.

Реализация

 int sum (int v, int tl, int tr, int l, int r)
 {
       if ([l,r] [math]\bigcap[/math] [tl, tr]) = 
           return 0;
       if ([l,r] [math]\subset[/math] [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);
 } 

Ссылки

- MAXimal :: algo :: Дерево отрезков

- Дерево отрезков — Википедия