<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.162.64.50&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=188.162.64.50&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/188.162.64.50"/>
		<updated>2026-06-12T07:19:42Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D1%83%D0%B3%D0%BE%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%D0%B0_%D1%81_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%BE%D0%BC_%D0%BD%D0%B5%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D0%BA%D0%B0%D1%8E%D1%89%D0%B8%D1%85%D1%81%D1%8F_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2_(segment_tree)&amp;diff=35794</id>
		<title>Пересечение прямоугольника с множеством непересекающихся отрезков (segment tree)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D1%83%D0%B3%D0%BE%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%D0%B0_%D1%81_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%BE%D0%BC_%D0%BD%D0%B5%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D0%BA%D0%B0%D1%8E%D1%89%D0%B8%D1%85%D1%81%D1%8F_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2_(segment_tree)&amp;diff=35794"/>
				<updated>2014-01-16T20:10:06Z</updated>
		
		<summary type="html">&lt;p&gt;188.162.64.50: /* Построение дерева */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Задача ==&lt;br /&gt;
Есть множество непересекающихся отрезков в &amp;lt;tex&amp;gt;\mathbb{R}^2&amp;lt;/tex&amp;gt;, нужно уметь отвечать на запросы, какие из них пересекают границу данного axis-aligned (стороны параллельны осям координат) прямоугольника.&lt;br /&gt;
&lt;br /&gt;
== Дерево отрезков ==&lt;br /&gt;
[[Файл:Segment_tree_1.png|400px|thumb|right|Пример дерева отрезков]]&lt;br /&gt;
Для решения задачи потребуется структура данных, которая называется дерево отрезков (segment tree). NB: по-русски этими словами принято обозначать несколько [[Дерево_отрезков._Построение | другую]] структуру данных, здесь не о ней.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;I = \{[x_1 : x_{1}'], [x_2 : x_{2}'], ..., [x_n : x_{n}']\}&amp;lt;/tex&amp;gt; — множество отрезков на вещественной оси. Возьмем концы этих отрезков и отсортируем их, получим точки &amp;lt;tex&amp;gt;p_1, p_2, ..., p_m&amp;lt;/tex&amp;gt;. Назовем множеством ''элементарных интервалов'' &amp;lt;tex&amp;gt;E = \{ (-\infty : p_1), [p_1 : p_1], (p_1 : p_2), ..., (p_m : +\infty) \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим сбалансированное бинарное дерево, листам которого будут соответствовать элементарные интервалы, а внутренним вершинам — объединения интервалов в потомках. &lt;br /&gt;
Будем обозначать интервал, соответствующий вершине &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;Int(v)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В каждой вершине будем хранить соответствующий ей интервал и множество отрезков &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt;, таких что &amp;lt;tex&amp;gt;I(v) \subset I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\forall [x : x'] \in I(v) : Int(v) \subset [x : x'], Int(parent(v)) \not\subset [x : x']&amp;lt;/tex&amp;gt;. По-человечески это значит, что интервал вершины должен полностью лежать внутри отрезка и выше таких вершин нет. По картинке должно быть понятно.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
Оценка на память&lt;br /&gt;
|statement=&lt;br /&gt;
Дерево отрезков занимает &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
|proof=&lt;br /&gt;
Всего элементарных интервалов не больше &amp;lt;tex&amp;gt;4n+1&amp;lt;/tex&amp;gt; (в случае, когда все отрезки не пересекаются: для каждого отрезок левее &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;[x : x]&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;(x : x')&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;[x' : x']&amp;lt;/tex&amp;gt; и еще один &amp;lt;tex&amp;gt;(p_m : +\infty)&amp;lt;/tex&amp;gt;). Так как дерево сбалансированное, его глубина &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Утверждается, что один отрезок на одной глубине встречается не более двух раз. Пусть это не так, возьмем три упорядоченные вершины &amp;lt;tex&amp;gt;v_1, v_2, v_3&amp;lt;/tex&amp;gt;, содержащие этот отрезок. Очевидно, что сосед &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; тоже содержит этот отрезок (см. картинку). Тогда этот отрезок должен содержаться в &amp;lt;tex&amp;gt;parent(v_2)&amp;lt;/tex&amp;gt;. Противоречие.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Segment_tree_proof.png]]&lt;br /&gt;
&lt;br /&gt;
Глубина &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, всего отрезков &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, на каждом уровне отрезок встречается &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; раз — победа.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Построение дерева ===&lt;br /&gt;
Сначала сортируем концы отрезков из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; собираем сбалансированное дерево (просто поднимаясь от листьев к корню и объединяя интервалы). Осталось найти &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt; для вершин дерева. Для этого вставим туда каждый отрезок по такому алгоритму:&lt;br /&gt;
 def '''InsertSegment'''(v, [x : x']):&lt;br /&gt;
   if &amp;lt;tex&amp;gt;Int(v) \subset [x : x']&amp;lt;/tex&amp;gt;:&lt;br /&gt;
     v.Add([x : x'])&lt;br /&gt;
   else:&lt;br /&gt;
     if &amp;lt;tex&amp;gt;Int(v.Left) \cap [x : x'] \neq \varnothing&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       InsertSegment(v.Left, [x : x'])&lt;br /&gt;
     if &amp;lt;tex&amp;gt;Int(v.Right) \cap [x : x'] \neq \varnothing&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       InsertSegment(v.Right, [x : x'])&lt;br /&gt;
Это работает за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, потому что на каждом уровне есть не более двух вершин, в которые отрезок нужно вставить и еще не более двух вершин, содержащих его концы. Таким образом, на каждом уровне нужно обработать не более четырех вершин. Итого для всех отрезков получаем &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запрос ===&lt;br /&gt;
Теперь научимся отвечать на запрос, какие отрезки содержат заданную точку.&lt;br /&gt;
 def '''Query'''(v, p, S):&lt;br /&gt;
   S = S &amp;lt;tex&amp;gt;\cup&amp;lt;/tex&amp;gt; I(v)&lt;br /&gt;
   if !v.IsLeaf:&lt;br /&gt;
     if &amp;lt;tex&amp;gt;p \in Int(v.Left)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       Query(v.Left, p)&lt;br /&gt;
     else&lt;br /&gt;
       Query(v.Right, p)&lt;br /&gt;
 Query(root, p, &amp;lt;tex&amp;gt;\varnothing&amp;lt;/tex&amp;gt;)&lt;br /&gt;
Запрос работает за &amp;lt;tex&amp;gt;O(\log n + k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; — размер ответа.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Чтобы решить исходную задачу, нужно уметь находить, какие отрезки из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; пересекают axis-aligned отрезок &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Рассмотрим случай, когда &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; параллелен оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; все делается аналогично.&lt;br /&gt;
&lt;br /&gt;
В дереве отрезков будем хранить их проекции на ось &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Это позволит найти, какие отрезки пересекают бесконечную вертикальную линию. Осталось найти, какие из них пересекают заданный отрезок.&lt;br /&gt;
&lt;br /&gt;
Используем то, что отрезки не пересекаются, и &amp;lt;tex&amp;gt;[x : x'] \in I(v) \Rightarrow Int(v) \subset [x : x']&amp;lt;/tex&amp;gt;: это значит, что отрезки внутри элементарного интервала могут быть вертикально упорядочены. В &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt; вместо списка теперь будем хранить дерево поиска.&lt;br /&gt;
&lt;br /&gt;
При запросе будем выдавать только те отрезки, для которых верхняя граница запроса выше точки пересечения с вертикальной линией, а нижняя — ниже (то есть все, что находится между lower_bound и upper_bound в дереве, проверяем выше/ниже поворотом).&lt;br /&gt;
&lt;br /&gt;
Таким образом, обработка одной вершины занимает &amp;lt;tex&amp;gt;O(\log n + k_v)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;k_v&amp;lt;/tex&amp;gt; — количество отрезков в ответе, полученных из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, всего посещенных вершин &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, итого &amp;lt;tex&amp;gt;O({\log}^2 n + k)&amp;lt;/tex&amp;gt;. Препроцессинг выполняется за &amp;lt;tex&amp;gt;O(n {\log}^2 n)&amp;lt;/tex&amp;gt; из-за вставки в дерево поиска.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Segment_tree Английская википедия]&lt;br /&gt;
* de Berg, van Kreveld, Overmars, Schwarzkopf &amp;quot;Computational Geometry Algorithms and Applications&amp;quot;, p. 231&lt;/div&gt;</summary>
		<author><name>188.162.64.50</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D1%83%D0%B3%D0%BE%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%D0%B0_%D1%81_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%BE%D0%BC_%D0%BD%D0%B5%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D0%BA%D0%B0%D1%8E%D1%89%D0%B8%D1%85%D1%81%D1%8F_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2_(segment_tree)&amp;diff=35785</id>
		<title>Пересечение прямоугольника с множеством непересекающихся отрезков (segment tree)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D1%83%D0%B3%D0%BE%D0%BB%D1%8C%D0%BD%D0%B8%D0%BA%D0%B0_%D1%81_%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D1%81%D1%82%D0%B2%D0%BE%D0%BC_%D0%BD%D0%B5%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D0%BA%D0%B0%D1%8E%D1%89%D0%B8%D1%85%D1%81%D1%8F_%D0%BE%D1%82%D1%80%D0%B5%D0%B7%D0%BA%D0%BE%D0%B2_(segment_tree)&amp;diff=35785"/>
				<updated>2014-01-16T17:51:02Z</updated>
		
		<summary type="html">&lt;p&gt;188.162.64.50: /* Дерево отрезков */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Задача ==&lt;br /&gt;
Есть множество непересекающихся отрезков в &amp;lt;tex&amp;gt;\mathbb{R}^2&amp;lt;/tex&amp;gt;, нужно уметь отвечать на запросы, какие из них пересекают границу данного axis-aligned (стороны параллельны осям координат) прямоугольника.&lt;br /&gt;
&lt;br /&gt;
== Дерево отрезков ==&lt;br /&gt;
[[Файл:Segment_tree_1.png|400px|thumb|right|Пример дерева отрезков]]&lt;br /&gt;
Для решения задачи потребуется структура данных, которая называется дерево отрезков (segment tree). NB: по-русски этими словами принято обозначать несколько [[Дерево_отрезков._Построение | другую]] структуру данных, здесь не о ней.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;I = \{[x_1 : x_{1}'], [x_2 : x_{2}'], ..., [x_n : x_{n}']\}&amp;lt;/tex&amp;gt; — множество отрезков на вещественной оси. Возьмем концы этих отрезков и отсортируем их, получим точки &amp;lt;tex&amp;gt;p_1, p_2, ..., p_m&amp;lt;/tex&amp;gt;. Назовем множеством ''элементарных интервалов'' &amp;lt;tex&amp;gt;E = \{ (-\infty : p_1), [p_1 : p_1], (p_1 : p_2), ..., (p_m : +\infty) \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим сбалансированное бинарное дерево, листам которого будут соответствовать элементарные интервалы, а внутренним вершинам — объединения интервалов в потомках. &lt;br /&gt;
Будем обозначать интервал, соответствующий вершине &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;Int(v)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В каждой вершине будем хранить соответствующий ей интервал и множество отрезков &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt;, таких что &amp;lt;tex&amp;gt;I(v) \subset I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\forall [x : x'] \in I(v) : Int(v) \subset [x : x'], Int(parent(v)) \not\subset [x : x']&amp;lt;/tex&amp;gt;. По-человечески это значит, что интервал вершины должен полностью лежать внутри отрезка и выше таких вершин нет. По картинке должно быть понятно.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
Оценка на память&lt;br /&gt;
|statement=&lt;br /&gt;
Дерево отрезков занимает &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
|proof=&lt;br /&gt;
Всего элементарных интервалов не больше &amp;lt;tex&amp;gt;4n+1&amp;lt;/tex&amp;gt; (в случае, когда все отрезки не пересекаются: для каждого отрезок левее &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;[x : x]&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;(x : x')&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;[x' : x']&amp;lt;/tex&amp;gt; и еще один &amp;lt;tex&amp;gt;(p_m : +\infty)&amp;lt;/tex&amp;gt;). Так как дерево сбалансированное, его глубина &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Утверждается, что один отрезок на одной глубине встречается не более двух раз. Пусть это не так, возьмем три упорядоченные вершины &amp;lt;tex&amp;gt;v_1, v_2, v_3&amp;lt;/tex&amp;gt;, содержащие этот отрезок. Очевидно, что сосед &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; тоже содержит этот отрезок (см. картинку). Тогда этот отрезок должен содержаться в &amp;lt;tex&amp;gt;parent(v_2)&amp;lt;/tex&amp;gt;. Противоречие.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Segment_tree_proof.png]]&lt;br /&gt;
&lt;br /&gt;
Глубина &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, всего отрезков &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, на каждом уровне отрезок встречается &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; раз — победа.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Построение дерева ===&lt;br /&gt;
Сначала сортируем концы отрезков из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; собираем сбалансированное дерево (просто поднимаясь от листьев к корню и объединяя интервалы). Осталось найти &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt; для вершин дерева. Для этого вставим туда каждый отрезок по такому алгоритму:&lt;br /&gt;
 def '''InsertSegment'''(v, [x : x']):&lt;br /&gt;
   if &amp;lt;tex&amp;gt;Int(v) \subset [x : x']&amp;lt;/tex&amp;gt;:&lt;br /&gt;
     v.Add([x : x'])&lt;br /&gt;
   else:&lt;br /&gt;
     if &amp;lt;tex&amp;gt;Int(v.Left) \cap [x : x ] \neq \varnothing&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       InsertSegment(v.Left, [x : x'])&lt;br /&gt;
     if &amp;lt;tex&amp;gt;Int(v.Right) \cap [x : x ] \neq \varnothing&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       InsertSegment(v.Right, [x : x'])&lt;br /&gt;
Это работает за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, потому что на каждом уровне есть не более двух вершин, в которые отрезок нужно вставить и еще не более двух вершин, содержащих его концы. Таким образом, на каждом уровне нужно обработать не более четырех вершин. Итого для всех отрезков получаем &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Запрос ===&lt;br /&gt;
Теперь научимся отвечать на запрос, какие отрезки содержат заданную точку.&lt;br /&gt;
 def '''Query'''(v, p, S):&lt;br /&gt;
   S = S &amp;lt;tex&amp;gt;\cup&amp;lt;/tex&amp;gt; I(v)&lt;br /&gt;
   if !v.IsLeaf:&lt;br /&gt;
     if &amp;lt;tex&amp;gt;p \in Int(v.Left)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
       Query(v.Left, p)&lt;br /&gt;
     else&lt;br /&gt;
       Query(v.Right, p)&lt;br /&gt;
 Query(root, p, &amp;lt;tex&amp;gt;\varnothing&amp;lt;/tex&amp;gt;)&lt;br /&gt;
Запрос работает за &amp;lt;tex&amp;gt;O(\log n + k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; — размер ответа.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Чтобы решить исходную задачу, нужно уметь находить, какие отрезки из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; пересекают axis-aligned отрезок &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;. Рассмотрим случай, когда &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; параллелен оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; все делается аналогично.&lt;br /&gt;
&lt;br /&gt;
В дереве отрезков будем хранить их проекции на ось &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Это позволит найти, какие отрезки пересекают бесконечную вертикальную линию. Осталось найти, какие из них пересекают заданный отрезок.&lt;br /&gt;
&lt;br /&gt;
Используем то, что отрезки не пересекаются, и &amp;lt;tex&amp;gt;[x : x'] \in I(v) \Rightarrow Int(v) \subset [x : x']&amp;lt;/tex&amp;gt;: это значит, что отрезки внутри элементарного интервала могут быть вертикально упорядочены. В &amp;lt;tex&amp;gt;I(v)&amp;lt;/tex&amp;gt; вместо списка теперь будем хранить дерево поиска.&lt;br /&gt;
&lt;br /&gt;
При запросе будем выдавать только те отрезки, для которых верхняя граница запроса выше точки пересечения с вертикальной линией, а нижняя — ниже (то есть все, что находится между lower_bound и upper_bound в дереве, проверяем выше/ниже поворотом).&lt;br /&gt;
&lt;br /&gt;
Таким образом, обработка одной вершины занимает &amp;lt;tex&amp;gt;O(\log n + k_v)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;k_v&amp;lt;/tex&amp;gt; — количество отрезков в ответе, полученных из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, всего посещенных вершин &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, итого &amp;lt;tex&amp;gt;O({\log}^2 n + k)&amp;lt;/tex&amp;gt;. Препроцессинг выполняется за &amp;lt;tex&amp;gt;O(n {\log}^2 n)&amp;lt;/tex&amp;gt; из-за вставки в дерево поиска.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Segment_tree Английская википедия]&lt;br /&gt;
* de Berg, van Kreveld, Overmars, Schwarzkopf &amp;quot;Computational Geometry Algorithms and Applications&amp;quot;, p. 231&lt;/div&gt;</summary>
		<author><name>188.162.64.50</name></author>	</entry>

	</feed>