<?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=93.92.200.173&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=93.92.200.173&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/93.92.200.173"/>
		<updated>2026-05-19T15:13:42Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Skip_quadtree:_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5,_%D0%B2%D1%80%D0%B5%D0%BC%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B&amp;diff=35951</id>
		<title>Skip quadtree: определение, время работы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Skip_quadtree:_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5,_%D0%B2%D1%80%D0%B5%D0%BC%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B&amp;diff=35951"/>
				<updated>2014-01-20T15:27:11Z</updated>
		
		<summary type="html">&lt;p&gt;93.92.200.173: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ready}}&lt;br /&gt;
== Описание ==&lt;br /&gt;
[[Файл:Skip_quadtree.png | 500px | thumb | По картинке должно быть понятно]]&lt;br /&gt;
Skip quadtree {{---}} как skip list, только вместо list'а quadtree. Поэтому желательно знать, что такое [[Список с пропусками | skip list]], и необходимо знать, что такое [[Квадродеревья#Сжатое квадродерево | сжатое квадродерево]]. В данной статье будет рассматриваться только рандомизированая версия этой структуры, потому что больше и не нужно, кажется.&lt;br /&gt;
&lt;br /&gt;
The randomized skip quadtree {{---}} последовательность сжатых квадродеревьев над последовательностью подмножеств некоторого исходного множества &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S_0 = S&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;S_1&amp;lt;/tex&amp;gt; каждый элемент из &amp;lt;tex&amp;gt;S_0&amp;lt;/tex&amp;gt; входит с вероятностью &amp;lt;tex&amp;gt;p \in (0, 1)&amp;lt;/tex&amp;gt; и так далее. The randomized skip quadtree состоит из последовательности &amp;lt;tex&amp;gt;\{Q_i\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt; {{---}} сжатое квадродерево над множеством &amp;lt;tex&amp;gt;S_i&amp;lt;/tex&amp;gt;. Будем называть эти квадродеревья уровнями, при этом нулевой уровень содержит в точности точки из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Заметим, что если какой-то квадрат [[Квадродеревья и перечисление точек в произвольном прямоугольнике (статика)#interesting | интересный]] в &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt;, то он интересный и в &amp;lt;tex&amp;gt;Q_{i-1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Операции над skip quadtree ==&lt;br /&gt;
Будем для каждого интересного квадрата на каждом уровне хранить указатели на тот же квадрат уровнем ниже и уровнем выше (если есть). &lt;br /&gt;
&lt;br /&gt;
Локализация выполняется аналогично сжатому квадродереву. Под локализацией подразумевается, что мы хотим найти минимальный интересный квадрат, содержащий данную точку (содержит геометрически, в самом дереве её может не быть, тут, возможно, правильнее сказать «пересекает»). Сначала локализуемся в квадродереве наибольшего уровня, начиная с его корня. Затем локализуемся в квадродереве уровня ниже, начиная уже не с корня, а с того квадрата, который нашли на прошлом уровне. И так далее, пока не дойдём до дна.&lt;br /&gt;
&lt;br /&gt;
Для добавления сначала надо локализоваться. При этом мы локализуемся сразу на всех уровнях (так уж устроен процесс). Дальше добавляемся в нулевой уровень, затем с вероятностью &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; добавляемся на уровень выше и так далее до первого недобавления. При этом количество уровней должно увеличиться максимум на 1, то есть, если появился новый уровень, то процесс точно заканчивается. Хотя не, давайте без последнего условия, вроде с ним только лучше, но без него проще доказывать.&lt;br /&gt;
&lt;br /&gt;
Удаление совсем просто: локализуемся, удаляем со всех уровней, на которых есть. При этом какой-то уровень мог стать пустым, в таком случае выкинем его.&lt;br /&gt;
&lt;br /&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(1)&amp;lt;/tex&amp;gt; шагов поиска для любой точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Пусть в &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt; (то есть на &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ом уровне) поиск точки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, начинающийся с корня, проходит по квадратам &amp;lt;tex&amp;gt;p_0, p_1, \dots, p_m&amp;lt;/tex&amp;gt;. Пусть случайная величина &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; {{---}} количество шагов поиска в &amp;lt;tex&amp;gt;Q_i&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;p_{m - j}&amp;lt;/tex&amp;gt; {{---}} последний квадрат из &amp;lt;tex&amp;gt;p_0, p_1, \dots, p_m&amp;lt;/tex&amp;gt;, являющийся интересным в &amp;lt;tex&amp;gt;Q_{i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Оценим вероятность того, что делается &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; шагов. Забьём на случай &amp;lt;tex&amp;gt;j = 0&amp;lt;/tex&amp;gt;, так как он не важен при расчёте мат. ожидания. На пути &amp;lt;tex&amp;gt;p_{m - j + 1} \dots, p_m&amp;lt;/tex&amp;gt; будет хотя бы &amp;lt;tex&amp;gt;j + 1&amp;lt;/tex&amp;gt; непустых четвертинок. У первого квадрата на этом пути есть хотя бы 2 непустые четвертинки, одна из них {{---}} следующий квадрат на пути, в котором тоже хотя бы 2 непустые четвертинки, и так далее. В последнем квадрате просто хотя бы 2 непустые четвертинки. Чтобы &lt;br /&gt;
&amp;lt;tex&amp;gt;p_{m - j}&amp;lt;/tex&amp;gt; был последним из &amp;lt;tex&amp;gt;p_0, p_1, \dots, p_m&amp;lt;/tex&amp;gt; интересным квадратом в &amp;lt;tex&amp;gt;Q_{i + 1}&amp;lt;/tex&amp;gt; небходимо, чтобы среди этих как минимум &amp;lt;tex&amp;gt;j + 1&amp;lt;/tex&amp;gt; непустых четвертинок только одна (вероятность этого назовём &amp;lt;tex&amp;gt;Pr_1&amp;lt;/tex&amp;gt;) или ноль (вероятность этого назовём &amp;lt;tex&amp;gt;Pr_0&amp;lt;/tex&amp;gt;) были непустыми в &amp;lt;tex&amp;gt;Q_{i + 1}&amp;lt;/tex&amp;gt;. Иначе, если будет хотя бы пара непустых четвертинок, то их наименьший общий предок в дереве будет интересным квадратом и будет находиться глубже &amp;lt;tex&amp;gt;p_{m - j}&amp;lt;/tex&amp;gt;. Таким образом, искомая вероятность не превосходит &amp;lt;tex&amp;gt;Pr_0 + Pr_1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
''Лично мне утверждение из предыдущего абзаца далось с трудом, если у вас тоже всё очень плохо, попробуйте напрячь мозг и залипнуть в картинку, вдруг поможет. Хотя я постарался расписать поподробней, чем в статье.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;q = 1 - p&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Pr_0 \leq q^{(j + 1)}&amp;lt;/tex&amp;gt;, потому что это в сущности вероятность того, что ни одна точка из как минимум &amp;lt;tex&amp;gt;j + 1&amp;lt;/tex&amp;gt; непустых четвертинок не попала на уровень выше.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Pr_1 \leq (j + 1) \cdot pq^j&amp;lt;/tex&amp;gt;, потому что это в сущности вероятность того, что ровно одна точка из как минимум &amp;lt;tex&amp;gt;j + 1&amp;lt;/tex&amp;gt; непустых четвертинок попала на уровень выше.&lt;br /&gt;
&lt;br /&gt;
''В общем, если чуть подумать, оценки на &amp;lt;tex&amp;gt;Pr_0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Pr_1&amp;lt;/tex&amp;gt; довольно ясны.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;E(j) = \sum\limits_{j = 1}^{m} j \cdot Pr(j) \leq \sum\limits_{j = 1}^{m} j \cdot (q^{(j + 1)} + (j + 1) \cdot pq^j) \leq \sum\limits_{j = 1}^{\infty} j \cdot (q^{(j + 1)} + (j + 1) \cdot pq^j)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&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;
|about=&lt;br /&gt;
О количестве уровней&lt;br /&gt;
|statement=&lt;br /&gt;
Математическое ожидание количества уровней составляет &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Для оценки мат. ожидания посчитаем вероятность того, что количество уровней &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;p(h = k) = p(h \leq k) \cdot p(h \geq k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(h \leq k) = (1 - p^{k + 1})^n&amp;lt;/tex&amp;gt;, потому что вероятность того, что точка дойдёт до уровня &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;, равна &amp;lt;tex&amp;gt;p^{k + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(h \geq k) = (1 - (1 - p^k)^n)&amp;lt;/tex&amp;gt;, потому что вероятность того, что точка не дойдёт до уровня &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, равна &amp;lt;tex&amp;gt;1 - p^k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
''А вот нифига не так, я тут понял. Там зависимые события, поэтому перемножать вероятности так нельзя, но всё не сильно портится. &amp;lt;tex&amp;gt;p(h = k) = 1 - p(h &amp;gt; k) - p(h &amp;lt; k) = 1 - (1 - (1 - p^{k + 1})^n) - (1 - p^{k})^n = (1 - p^{k + 1})^n - (1 - p^k)^n \leq 1 - (1 - p^k)^n \leq np^k&amp;lt;/tex&amp;gt;, и дальше этой оценки достаточно.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;E(h) = \sum\limits_{k = 1}^{\infty} k \cdot p(h = k) = p(1) \cdot 1 + \dots + p(\log_{1/p} n) \cdot \log_{1/p} n + \sum\limits_{k = \log_{1/p} n + 1}^{\infty} k \cdot p(k)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценим первую сумму:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;p(1) \cdot 1 + \dots + p(\log_{1/p} n) \cdot \log_{1/p} n \leq p(1) \cdot \log_{1/p} n + \dots + p(\log_{1/p} n) \cdot \log_{1/p} n = O(\log(n))&amp;lt;/tex&amp;gt;, поскольку сумма этих вероятностей не превосходит единицу.&lt;br /&gt;
&lt;br /&gt;
Оценим вторую сумму:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{k = \log_{1/p} n + 1}^{\infty} k \cdot p(k) = \leq \sum\limits_{k = \log_{1/p} n}^{\infty} k \cdot n p^k = n \cdot \sum\limits_{k = \log_{1/p} n}^{\infty} k \cdot p^k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим эту сумму:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum\limits_{k = \log_{1/p} n}^{\infty} k \cdot p^k = p^{\log_{1/p} n} \cdot \sum\limits_{k = 0}^{\infty} (k + \log_{1/p} n) \cdot p^k = p^{\log_{1/p} n} \cdot (\sum\limits_{k = 0}^{\infty} (k p^k) + \log_{1/p} n \cdot \sum\limits_{k = 0}^{\infty} (p^k)) =  p^{\log_{1/p} n} \cdot (O(1) + \log_{1/p} n \cdot O(1)) = 1/n \cdot O(\log(n))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&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;p = 1/2&amp;lt;/tex&amp;gt;.''&lt;br /&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(\log(n))&amp;lt;/tex&amp;gt; в среднем.&lt;br /&gt;
|proof=&lt;br /&gt;
Достаточно очевидно из предыдущих лемм.&lt;br /&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)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Сжатое квадродерево для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек занимает &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; памяти. На нулевом уровне &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; точек. На следующем уровне &amp;lt;tex&amp;gt;p \cdot n&amp;lt;/tex&amp;gt; точек, дальше &amp;lt;tex&amp;gt;p^2 \cdot n&amp;lt;/tex&amp;gt; и так далее. Получим геометрическую прогрессию, в итоге &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; памяти.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== В чём профит? ==&lt;br /&gt;
Как и [[Перечисление точек в произвольном прямоугольнике за n * log ^(d - 1) n (range tree) | range tree]], данная структура умеет выдавать точки, принадлежащие какому-то прямоугольнику, алгоритм очень похож на тот, который применяется в range tree. Только ответ на запрос происходит за &amp;lt;tex&amp;gt;O(\log n + k)&amp;lt;/tex&amp;gt; (вроде бы независимо от размерности, хотя квадродерево подразумевает двумерное пространство, но для обобщения на больше размерности асимптотика будет та же, кажется). И памяти нужно &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;. Этим skip quadtree круче.&lt;br /&gt;
&lt;br /&gt;
=== Как отвечать на запрос ===&lt;br /&gt;
Сначала локализуем все четыре точки прямоугольника&lt;br /&gt;
&lt;br /&gt;
''Я тут понял, что пока не знаю, как это делать, сейчас буду думать.''&lt;br /&gt;
&lt;br /&gt;
''Всё очень плохо, я тупой, меня можно побить.''&lt;br /&gt;
&lt;br /&gt;
''Боря тоже не знает, так что я не тупой, меня не надо бить. А ещё выяснилось, что от нас это не требуется, так что особо любознательные могут сами подумать, а остальные могут просто забить.&lt;br /&gt;
&lt;br /&gt;
== Источник ==&lt;br /&gt;
http://arxiv.org/pdf/cs.cg/0507049.pdf&lt;br /&gt;
&lt;br /&gt;
[[Категория: Вычислительная геометрия]]&lt;/div&gt;</summary>
		<author><name>93.92.200.173</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D1%8B%D0%B5_(%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5)_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B8&amp;diff=34491</id>
		<title>Разрешимые (рекурсивные) языки</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A0%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D1%8B%D0%B5_(%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5)_%D1%8F%D0%B7%D1%8B%D0%BA%D0%B8&amp;diff=34491"/>
				<updated>2013-12-21T12:32:27Z</updated>
		
		<summary type="html">&lt;p&gt;93.92.200.173: Добавил id к определению универсального языка, чтобы ссылаться на него из других конспектов&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; называется '''разрешимым''' ('''рекурсивным, recursive language'''), если существует такая программа &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt; \forall w \in L: p(w) = 1&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; \forall w \notin L: p(w) = 0&amp;lt;/tex&amp;gt;. Класс всех разрешимых языков часто обозначается через &amp;lt;tex&amp;gt; \mathrm{R} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример разрешимого множества==&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=st1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык чётных чисел разрешим.&lt;br /&gt;
|proof=&lt;br /&gt;
Приведём программу, разрешающую язык чётных чисел:&lt;br /&gt;
 &amp;lt;tex&amp;gt;p(i):&amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''if''' &amp;lt;tex&amp;gt; i \  mod \  2 == 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''else'''&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt; 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
Заметим, что программа нигде не может зависнуть.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример неразрешимого множества==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id=uni&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;\  U = \{\langle p, x \rangle \ |\ p(x) = 1\} &amp;lt;/tex&amp;gt; называется '''универсальным''' ('''universal language''').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=st1&lt;br /&gt;
|statement=&lt;br /&gt;
Универсальный язык неразрешим.&lt;br /&gt;
|proof=&lt;br /&gt;
Приведём доказательство от противного. &amp;lt;br/&amp;gt;&lt;br /&gt;
Пусть язык &amp;lt;tex&amp;gt; U &amp;lt;/tex&amp;gt; разрешим. Тогда существует такая программа &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt; \forall \langle p, x \rangle \in U: u(\langle p, x \rangle) = 1&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt; \forall \langle p, x \rangle \notin U: u(\langle p, x \rangle) = 0&amp;lt;/tex&amp;gt;. &amp;lt;br/&amp;gt;&lt;br /&gt;
Составим следующую программу:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;r(x):&amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''if''' &amp;lt;tex&amp;gt; u(\langle x, x \rangle) == 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; true &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''else'''&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим вызов &amp;lt;tex&amp;gt; r(r) &amp;lt;/tex&amp;gt;:&lt;br /&gt;
* если &amp;lt;tex&amp;gt; u(\langle r, r \rangle) = 1 &amp;lt;/tex&amp;gt;, то условие '''if''' выполнится и программа зависнет. Но так как программа &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; разрешает универсальный язык, &amp;lt;tex&amp;gt; u(\langle r, r \rangle) = 1 \Rightarrow r(r) = 1&amp;lt;/tex&amp;gt;;&lt;br /&gt;
* если &amp;lt;tex&amp;gt; u(\langle r, r \rangle) = 0 &amp;lt;/tex&amp;gt;, то условие '''if''' не выполнится и программа вернет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Но так как программа &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; разрешает универсальный язык, &amp;lt;tex&amp;gt; u(\langle r, r \rangle) = 0 \Rightarrow r(r) \ne 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, из предположения о разрешимости универсального языка мы пришли к противоречию.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Н. К. Верещагин, А. Шень. Лекции по математической логике и теории алгоритмов. Часть 3. Вычислимые функции. — М.: МЦНМО, 1999. С. 134. ISBN 5-900916-36-7&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Recursive_language Wikipedia — Recursive language]&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA Википедия — Рекурсивный язык]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Теория вычислимости]]&lt;/div&gt;</summary>
		<author><name>93.92.200.173</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE&amp;diff=31868</id>
		<title>Декартово дерево</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE&amp;diff=31868"/>
				<updated>2013-06-11T18:34:13Z</updated>
		
		<summary type="html">&lt;p&gt;93.92.200.173: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''Эта статья про Курево''&lt;br /&gt;
&lt;br /&gt;
'''Декартово дерево''' {{---}} это структура данных, объединяющая в себе бинарное дерево поиска и бинарную кучу (отсюда и второе её название: treap (tree + heap) и дерамида (дерево + пирамида), также существует название курево (куча + дерево).&lt;br /&gt;
&lt;br /&gt;
Более строго, это бинарное дерево, в узлах которого хранится пары &amp;lt;tex&amp;gt; (x,y) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;x&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; и [[Двоичная куча|пирамидой]] по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Предполагая, что все &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и все &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; являются различными, получаем, что если некоторый элемент дерева содержит &amp;lt;tex&amp;gt;(x_0,y_0)&amp;lt;/tex&amp;gt;, то у всех элементов в левом поддереве &amp;lt;tex&amp;gt;x &amp;lt; x_0&amp;lt;/tex&amp;gt;, у всех элементов в правом поддереве &amp;lt;tex&amp;gt; x &amp;gt; x_0&amp;lt;/tex&amp;gt;, а также и в левом, и в правом поддереве имеем: &amp;lt;tex&amp;gt; y &amp;lt; y_0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дерамиды были предложены Сиделем (Siedel) и Арагоном (Aragon) в 1996 г.&lt;br /&gt;
&lt;br /&gt;
== Операции в декартовом дереве ==&lt;br /&gt;
=== Split ===&lt;br /&gt;
[[file:split.png|thumb|400px|Операция split]]&lt;br /&gt;
&lt;br /&gt;
Операция &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt; (''разрезать'') позволяет сделать следующее: разрезать декартово дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; по ключу &lt;br /&gt;
&amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и получить два других декартовых дерева: &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;, причем в &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
находятся все ключи дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, не большие &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; {{---}} большие &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{Split}(T, k) \to \{T_1, T_2\}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Эта операция устроена следующим образом.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай, в котором требуется разрезать дерево по ключу, большему ключа корня.&lt;br /&gt;
Посмотрим, как будут устроены результирующие деревья &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;:&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;: левое поддерево &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; совпадёт с левым поддеревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Для нахождения правого поддерева &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;, нужно разрезать правое поддерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;T^R_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T^R_2&amp;lt;/tex&amp;gt; по ключу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и взять &amp;lt;tex&amp;gt;T^R_1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; совпадёт с &amp;lt;tex&amp;gt;T^R_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Случай, в котором требуется разрезать дерево по ключу, меньше либо равному ключа в корне, рассматривается симметрично.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Split(Treap t, int k, Treap &amp;amp;t1, Treap &amp;amp;t2)&lt;br /&gt;
  if t == NULL &lt;br /&gt;
    t1 = t2 = NULL;&lt;br /&gt;
  else if k &amp;gt; t.x &lt;br /&gt;
    Split(t.right, k, t.right, t2);&lt;br /&gt;
    t1 = t;&lt;br /&gt;
  else &lt;br /&gt;
    Split(t.left, k, t1, t.left);&lt;br /&gt;
    t2 = t;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оценим время работы операции &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt;. Во время выполнения вызывается одна операция &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt; для&lt;br /&gt;
дерева хотя бы на один меньшей высоты и делается ещё &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; операция. Тогда итоговая трудоёмкость этой операции&lt;br /&gt;
равна &amp;lt;tex&amp;gt;O(h)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} высота дерева.&lt;br /&gt;
&lt;br /&gt;
=== Merge ===&lt;br /&gt;
[[file:merge.png|thumb|400px|Операция merge]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим вторую операцию с декартовыми деревьями {{---}} &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt; (''слить''). &lt;br /&gt;
&lt;br /&gt;
С помощью этой операции можно слить два декартовых дерева в одно.&lt;br /&gt;
Причем, все ключи в первом(''левом'') дереве должны быть меньше, чем&lt;br /&gt;
ключи во втором(''правом''). В результате получается дерево, в котором есть все ключи из первого и второго деревьев.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{Merge}(T_1, T_2) \to \{T\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим принцип работы этой операции. Пусть нужно слить деревья &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Тогда, очевидно, у результирующего дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; есть корень. &lt;br /&gt;
Корнем станет вершина из &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; с наибольшим ключом &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Но вершина с самым большим &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; из всех вершин деревьев &lt;br /&gt;
&amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; может быть только либо корнем &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;, либо корнем &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Рассмотрим случай, в котором корень &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; имеет больший &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, чем корень &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Случай, в котором корень &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; имеет больший &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, чем корень &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;, симметричен этому.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; корня &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; больше &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; корня &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;, то он и будет являться корнем. Тогда левое поддерево &lt;br /&gt;
&amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; совпадёт с левым поддеревом &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt;. Справа же нужно подвесить объединение правого поддерева&lt;br /&gt;
&amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и дерева &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Merge(Treap &amp;amp;t, Treap t1, Treap t2)&lt;br /&gt;
  if t1 == NULL or t2 == NULL &lt;br /&gt;
    if t1 != NULL&lt;br /&gt;
      t = t1;&lt;br /&gt;
    else&lt;br /&gt;
      t = t2;&lt;br /&gt;
  else if t1.y &amp;gt; t2.y&lt;br /&gt;
    Merge(t1.right, t1.right, t2);&lt;br /&gt;
    t = t1;&lt;br /&gt;
  else &lt;br /&gt;
    Merge(t2.left, t1, t2.left);&lt;br /&gt;
    t = t2;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассуждая аналогично операции &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt; приходим к выводу, что трудоёмкость операции &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt; &lt;br /&gt;
равна &amp;lt;tex&amp;gt;O(h)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} высота дерева.&lt;br /&gt;
&lt;br /&gt;
=== Insert ===&lt;br /&gt;
Операция &amp;lt;tex&amp;gt;\mathrm{Insert}(T, k)&amp;lt;/tex&amp;gt; добавляет в дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; элемент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k.x&amp;lt;/tex&amp;gt; {{---}} ключ, а &amp;lt;tex&amp;gt;k.y&amp;lt;/tex&amp;gt;{{---}} приоритет.&lt;br /&gt;
&lt;br /&gt;
Представим что элемент &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, это декартово дерево из одного элемента, и для того чтобы его добавить в наше декартово дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, очевидно, нам нужно их слить. Но &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может содержать ключи как меньше, так и больше ключа &amp;lt;tex&amp;gt;k.x&amp;lt;/tex&amp;gt;, поэтому сначала нужно разрезать &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; по ключу &amp;lt;tex&amp;gt;k.x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Реализация №1 &lt;br /&gt;
# Разобьём наше дерево по ключу, который мы хотим добавить, то есть &amp;lt;tex&amp;gt;\mathrm{Split}(T, k.x) \to \{T_1, T_2\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Сливаем первое дерево с новым элементом, то есть &amp;lt;tex&amp;gt;\mathrm{Merge}(T_1, k) \to T_1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Сливаем получившиеся дерево со вторым, то есть &amp;lt;tex&amp;gt;\mathrm{Merge}(T_1, T_2) \to T&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Реализация №2  &lt;br /&gt;
# Сначала спускаемся по дереву (как в обычном бинарном дереве поиска по &amp;lt;tex&amp;gt;k.x&amp;lt;/tex&amp;gt;), но останавливаемся на первом элементе, в котором значение приоритета оказалось меньше &amp;lt;tex&amp;gt;k.y&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь вызываем &amp;lt;tex&amp;gt;\mathrm{Split}(T, k.x) \to \{T_1, T_2\}&amp;lt;/tex&amp;gt; от найденного элемента (от элемента вместе со всем его поддеревом) &lt;br /&gt;
# Полученные &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; записываем в качестве левого и правого сына добавляемого элемента.&lt;br /&gt;
# Полученное дерево ставим на место элемента, найденного в первом пункте.&lt;br /&gt;
&lt;br /&gt;
В первой реализации два раза используется &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt;, а во второй реализации слияние вообще не используется.&lt;br /&gt;
&lt;br /&gt;
=== Remove ===&lt;br /&gt;
Операция &amp;lt;tex&amp;gt;\mathrm{Remove}(T, x)&amp;lt;/tex&amp;gt; удаляет из дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; элемент с ключом &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Реализация №1&lt;br /&gt;
&lt;br /&gt;
# Разобьём наше дерево по ключу, который мы хотим удалить, то есть &amp;lt;tex&amp;gt;\mathrm{Split }(T, k.x) \to \{T_1, T_2\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь отделяем от первого дерева элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, опять таки разбивая по ключу &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{Split }(T_1, k.x - \varepsilon) \to \{T_1, T_3\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Сливаем первое дерево со вторым, то есть &amp;lt;tex&amp;gt;\mathrm{Merge }(T_1, T_2) \to T&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
* Реализация №2&lt;br /&gt;
# Спускаемся по дереву (как в обычном бинарном дереве поиска по &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;), ища удаляемый элемент. &lt;br /&gt;
# Найдя элемент, вызываем &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt; его левого и правого сыновей&lt;br /&gt;
# Результат процедуры &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt; ставим на место удаляемого элемента.&lt;br /&gt;
&lt;br /&gt;
В первой реализации два раза используется &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt;, а во второй реализации разрезание вообще не используется.&lt;br /&gt;
&lt;br /&gt;
== Построение декартова дерева ==&lt;br /&gt;
Пусть нам известно из каких пар &amp;lt;tex&amp;gt;(x_i, y_i)&amp;lt;/tex&amp;gt; требуется построить декартово дерево, причем также известно, что &amp;lt;tex&amp;gt;x_1 &amp;lt; x_2 &amp;lt; \ldots &amp;lt; x_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Рекурсивный алгоритм ===&lt;br /&gt;
Рассмотрим приоритеты &amp;lt;tex&amp;gt;y_1 , y_2 , \ldots , y_n&amp;lt;/tex&amp;gt; и выберем максимум среди них, пусть это будет &amp;lt;tex&amp;gt;y_k&amp;lt;/tex&amp;gt;, и сделаем &amp;lt;tex&amp;gt;(x_k, y_k)&amp;lt;/tex&amp;gt; корнем дерева (по свойству [[Двоичная куча|пирамиды]] в корне должен быть элемент с максимальным приоритетом). Проделав то же самое с &amp;lt;tex&amp;gt;y_1 , y_2 , \ldots , y_{k-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_{k+1} , y_{k+2} , \ldots , y_n&amp;lt;/tex&amp;gt;, получим соответственно левого и правого сына &amp;lt;tex&amp;gt;(x_k, y_k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Такой алгоритм работает за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Алгоритм за O(n) ===&lt;br /&gt;
Будем строить дерево слева направо, то есть начиная с &amp;lt;tex&amp;gt;(x_1, y_1)&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;(x_n, y_n)&amp;lt;/tex&amp;gt;, при этом помнить последний добавленный элемент &amp;lt;tex&amp;gt;(x_k, y_k)&amp;lt;/tex&amp;gt;. Он будет самым правым, так как у него будет максимальный ключ, а по ключам декартово дерево представляет собой [[Дерево поиска, наивная реализация|двоичное дерево поиска]]. При добавлении &amp;lt;tex&amp;gt;(x_{k+1}, y_{k+1})&amp;lt;/tex&amp;gt;, пытаемся сделать его правым сыном &amp;lt;tex&amp;gt;(x_k, y_k)&amp;lt;/tex&amp;gt;, это следует сделать если &amp;lt;tex&amp;gt;y_k &amp;gt; y_{k+1}&amp;lt;/tex&amp;gt;, иначе делаем шаг к предку последнего элемента и смотрим его значение &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Поднимаемся до тех пор, пока приоритет в рассматриваемом элементе меньше приоритета в добавляемом, после чего делаем &amp;lt;tex&amp;gt;(x_{k+1}, y_{k+1})&amp;lt;/tex&amp;gt; его правым сыном, а предыдущего правого сына делаем левым сыном &amp;lt;tex&amp;gt;(x_{k+1}, y_{k+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что каждую вершину мы посетим максимум дважды: при непосредственном добавлении и, поднимаясь вверх (ведь после этого вершина будет лежать в чьем-то левом поддереве, а мы поднимаемся только по правому). Из этого следует, что построение происходит за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Случайные приоритеты ==&lt;br /&gt;
Мы уже выяснили, что сложность операций с декартовым деревом линейно зависит от его высоты. В действительности высота декартова дерева может быть линейной относительно его размеров. Например, высота декартова дерева, построенного по набору ключей &amp;lt;tex&amp;gt;(1, 1), \ldots, (n, n)&amp;lt;/tex&amp;gt;, будет равна &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Во избежание таких случаев, полезным оказывается выбирать приоритеты в ключах случайно.&lt;br /&gt;
&lt;br /&gt;
== Высота в декартовом дереве с случайными приоритетами ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement = В декартовом дереве из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; узлов, приоритеты &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; которого являются [[Дискретная случайная величина|случайными величинами]] c равномерным распределением, средняя глубина вершины &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
&lt;br /&gt;
Будем считать, что все выбранные приоритеты &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; попарно различны.&lt;br /&gt;
&lt;br /&gt;
Для начала введем несколько обозначений:&lt;br /&gt;
* &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; {{---}} вершина с &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;-ым по величине ключом;&lt;br /&gt;
* индикаторная величина &amp;lt;tex&amp;gt;A_{i, j} = \left\{\begin{array}{lllc} 1 &amp;amp;&amp;amp;, x_i\  \text{is ancestor of} \ x_j\\ &lt;br /&gt;
0 &amp;amp;&amp;amp;, \text{otherwise}\\&lt;br /&gt;
\end{array}\right.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt;d(v)&amp;lt;/tex&amp;gt; - глубина вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
В силу обозначений глубину вершины можно записать как количество предков:&lt;br /&gt;
:&amp;lt;tex&amp;gt;d(x_k) = \sum\limits_{i = 1}^{n} A_{i,k} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь можно выразить [[Математическое ожидание случайной величины|математическое ожидание]] глубины конкретной вершины:&lt;br /&gt;
:&amp;lt;tex&amp;gt;E(d(x_k)) = \sum\limits_{i = 1}^{n} Pr[A_{i,k} = 1] &amp;lt;/tex&amp;gt; {{---}} здесь мы использовали линейность математического ожидания, и то что &amp;lt;tex&amp;gt;E(X) = Pr[X = 1]&amp;lt;/tex&amp;gt; для индикаторной величины &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;Pr[A]&amp;lt;/tex&amp;gt; {{---}} вероятность события &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;).&lt;br /&gt;
Для подсчёта средней глубины вершин нам нужно сосчитать вероятность того,  что вершина &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; является предком вершины &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;Pr[A_{i,k} = 1]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Введем новое обозначение:&lt;br /&gt;
* &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt; {{---}}  множество ключей &amp;lt;tex&amp;gt;\{x_i, \ldots, x_k\}&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;\{x_k, \ldots, x_i\}&amp;lt;/tex&amp;gt;,  в зависимости от &amp;lt;tex&amp;gt;i &amp;lt; k&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;i &amp;gt; k&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X_{k, i}&amp;lt;/tex&amp;gt; обозначают одно и тоже, их мощность равна &amp;lt;tex&amp;gt;|k - i| + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=Для любых &amp;lt;tex&amp;gt;i \ne k&amp;lt;/tex&amp;gt; , &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; является предком &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; имеет наименьший приоритет среди &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Если &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; является корнем, то оно является предком &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; и по определению имеет минимальный приоритет среди всех вершин, следовательно, и среди &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
С другой стороны,  если &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; {{---}}  корень,  то &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; {{---}}  не предок &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; имеет минимальный приоритет в декартовом дереве; следовательно, &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; не имеет наименьший приоритет среди &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь предположим, что какая-то другая   вершина &amp;lt;tex&amp;gt;x_m&amp;lt;/tex&amp;gt; – корень. Тогда, если &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; лежат в разных поддеревьях, то &amp;lt;tex&amp;gt;i &amp;lt; m &amp;lt; k&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;i &amp;gt; m &amp;gt; k&amp;lt;/tex&amp;gt;, следовательно, &amp;lt;tex&amp;gt;x_m&amp;lt;/tex&amp;gt; содержится в &amp;lt;tex&amp;gt;X_{i , k}&amp;lt;/tex&amp;gt;. В этом случае &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; – не предок &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt;, и наименьший приоритет среди &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt; имеет вершина с номером &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Наконец,  если &amp;lt;tex&amp;gt;x_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x_k&amp;lt;/tex&amp;gt; лежат в одном поддереве,  то доказательство применяется по индукции: пустое декартово дерево есть тривиальная база,  а рассматриваемое поддерево является меньшим декартовым деревом. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Так как распределение приоритетов равномерное, каждая вершина среди &amp;lt;tex&amp;gt;X_{i, k}&amp;lt;/tex&amp;gt; может иметь минимальный приоритет,  мы немедленно приходим к следующему равенству: &lt;br /&gt;
: &amp;lt;tex&amp;gt;Pr[A_{i, j} = 1] = \left\{\begin{array}{lllc} \frac{1}{k - i + 1} &amp;amp;&amp;amp;, k \ &amp;gt; \ i\\ &lt;br /&gt;
0 &amp;amp;&amp;amp;, k\ =\ i\\&lt;br /&gt;
\frac{1}{i - k + 1} &amp;amp;&amp;amp;, k \ &amp;lt; \ i\\&lt;br /&gt;
\end{array}\right.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив последнее в нашу формулу с математическим ожиданием получим:&lt;br /&gt;
: &amp;lt;tex&amp;gt;E(d(x_k)) = \sum\limits_{i = 1}^{n} Pr[A_{i,k} = 1] = \sum\limits_{i = 1}^{k - 1}  \frac{1}{k - i + 1} + \sum\limits_{i = k + 1}^{n} \frac{1}{i - k + 1} \le \ln(k) + \ln(n-k) + 2&amp;lt;/tex&amp;gt; (здесь мы использовали неравенство &amp;lt;tex&amp;gt;\sum\limits_{i = 1}^{n}  \frac{1}{i} \le \ln(n) + 1&amp;lt;/tex&amp;gt;)&lt;br /&gt;
: &amp;lt;tex&amp;gt;\log(n)&amp;lt;/tex&amp;gt; отличается от &amp;lt;tex&amp;gt;\ln(n)&amp;lt;/tex&amp;gt; в константу раз, поэтому &amp;lt;tex&amp;gt;\log(n) = O(\ln(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В итоге мы получили что &amp;lt;tex&amp;gt;E(d(x_k)) = O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, среднее время работы операций &amp;lt;tex&amp;gt;\mathrm{Split}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Merge}&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Декартово дерево по неявному ключу]]&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Декартово_дерево Декартово дерево — Википедия]&lt;br /&gt;
*[http://rain.ifmo.ru/cat/data/theory/trees/treaps-2006/article.pdf Treaps и T-Treaps]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Деревья поиска]]&lt;/div&gt;</summary>
		<author><name>93.92.200.173</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%AD%D0%B4%D0%BC%D0%BE%D0%BD%D0%B4%D1%81%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0&amp;diff=30895</id>
		<title>Алгоритм Эдмондса-Карпа</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%AD%D0%B4%D0%BC%D0%BE%D0%BD%D0%B4%D1%81%D0%B0-%D0%9A%D0%B0%D1%80%D0%BF%D0%B0&amp;diff=30895"/>
				<updated>2013-06-01T19:12:27Z</updated>
		
		<summary type="html">&lt;p&gt;93.92.200.173: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Алгоритм ==&lt;br /&gt;
&lt;br /&gt;
Для заданной сети &amp;lt;tex&amp;gt;G(V, E, c)&amp;lt;/tex&amp;gt; алгоритм Эдмондса-Карпа находит поток максимальной величины из заданного истока &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в заданный сток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(V E^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&lt;br /&gt;
 '''Edmonds_Karp''' (G, s, t)&lt;br /&gt;
     '''for''' (для) каждого ребра &amp;lt;tex&amp;gt;(u,v) \in E[G]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''do''' &amp;lt;tex&amp;gt;f[u,v] \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;f[v,u] \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
     '''while''' существует ''кратчайший'' путь &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в остаточной сети &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''do''' &amp;lt;tex&amp;gt;c_f(p) \leftarrow min\{c_f(u,v) : (u,v) \in p\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''for''' (для) каждого ребра &amp;lt;tex&amp;gt;(u,v) \in p&amp;lt;/tex&amp;gt;&lt;br /&gt;
                 '''do''' &amp;lt;tex&amp;gt;f[u,v] \leftarrow f[u,v] + c_f(p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
                    &amp;lt;tex&amp;gt;f[v,u] \leftarrow -f[u,v]&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Корректность алгоритма Эдмондса-Карпа ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм Эдмондса-Карпа является реализацией метода [[Алгоритм Форда-Фалкерсона для поиска максимального паросочетания|Форда-Фалкерсона]]. На каждой итерации цикла '''while''' поток в графе &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; увеличивается вдоль одного из кратчайших путей в &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt; из истока &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в сток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Этот процесс повторяется до тех пор пока существует кратчайший &amp;lt;tex&amp;gt;s \leadsto t&amp;lt;/tex&amp;gt; путь в &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt; не существует кратчайшего пути из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, значит, не существует никакого вообще никакого &amp;lt;tex&amp;gt;s \leadsto t&amp;lt;/tex&amp;gt; пути в &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt; следовательно по [[Теорема Форда-Фалкерсона|теореме Форда-Фалкерсона]] найденный поток &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; максимальный.&lt;br /&gt;
&lt;br /&gt;
== Оценка быстродействия ==&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement=&lt;br /&gt;
Если в сети &amp;lt;tex&amp;gt;G(V,E)&amp;lt;/tex&amp;gt; с источником &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; и стоком &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; увеличение потока производится вдоль кратчайших &amp;lt;tex&amp;gt;s \leadsto t&amp;lt;/tex&amp;gt; путей в &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt;, то для всех вершин &amp;lt;tex&amp;gt;v \in V\backslash\{s,t\}&amp;lt;/tex&amp;gt; длина кратчайшего пути &amp;lt;tex&amp;gt;\delta_f(s, v)&amp;lt;/tex&amp;gt; в остаточной сети &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt; не убывает после каждого увеличения потока.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим противное, пусть существует вершина &amp;lt;tex&amp;gt;v \in V \backslash\{s,t\}&amp;lt;/tex&amp;gt;, что после какого-то увеличения потока длина кратчайшего пути из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; уменьшилась. Обозначим потоки до и после увеличения соответственно за &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f'&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; {{---}} вершина, расстояние &amp;lt;tex&amp;gt;\delta'_f(s,v)&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; до которой минимально и уменьшилось с увеличением потока. Имеем &amp;lt;tex&amp;gt;\delta'_f(s,v) &amp;lt; \delta_f(s,v)&amp;lt;/tex&amp;gt;. Рассмотрим путь &amp;lt;tex&amp;gt;p = s \leadsto u \rightarrow v&amp;lt;/tex&amp;gt;, являющийся кратчайшим от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G'_f&amp;lt;/tex&amp;gt;. Тогда верно, что &amp;lt;tex&amp;gt;\delta'_f(s, u) = \delta'_f(s,v) - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
По выбору &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и из предыдущего утверждения получаем, что &amp;lt;tex&amp;gt;\delta'_f (s, u) \ge \delta_f(s,u)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим &amp;lt;tex&amp;gt;(u, v) \in E_f&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;\delta_f(s,v) \le \delta_f(s, u) + 1 \le \delta'_f(s,u) + 1 = \delta'_f(s, v)&amp;lt;/tex&amp;gt;. Это противоречит &amp;lt;tex&amp;gt;\delta'_f(s,v) &amp;lt; \delta_f(s,v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;(u,v) \notin E_f&amp;lt;/tex&amp;gt;, но известно, что &amp;lt;tex&amp;gt;(u,v) \in E_f'&amp;lt;/tex&amp;gt;. Появление ребра &amp;lt;tex&amp;gt;(u,v)&amp;lt;/tex&amp;gt; после увеличения потока означает увеличение потока по обратному ребру &amp;lt;tex&amp;gt;(v, u)&amp;lt;/tex&amp;gt;. Увеличение потока производится вдоль кратчайшего пути, поэтому кратчайший путь из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; вдоль которого происходило увеличения выглядит как &amp;lt;tex&amp;gt;s \leadsto v \rightarrow u&amp;lt;/tex&amp;gt;, из чего получаем &amp;lt;tex&amp;gt;\delta_f(s, v) = \delta_f(s, u) - 1 \le \delta'_f(s, u) - 1 = \delta'(s, v) - 2&amp;lt;/tex&amp;gt;. Данное утверждение противоречит &amp;lt;tex&amp;gt;\delta'_f(s,v) &amp;lt; \delta_f(s,v)&amp;lt;/tex&amp;gt;. Итак мы пришли к противоречию с существованием вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, кратчайшее расстояние до которой уменьшилось с увеличением потока.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Опираясь на предшествующую лемму, докажем следующую теорему, которая ограничивает сверху число итераций цикла '''while''' в алгоритме Эдмондса-Карпа.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Пусть для некоторой сети &amp;lt;tex&amp;gt;G(V,E)&amp;lt;/tex&amp;gt; с источником &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; и стоком &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; выполняется алгоритм Эдмондса-Карпа, то общее число итераций цикла '''while''' составляет &amp;lt;tex&amp;gt;O(V E)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим множество ребер &amp;lt;tex&amp;gt;(u,v)&amp;lt;/tex&amp;gt; остаточной сети &amp;lt;tex&amp;gt;G_f&amp;lt;/tex&amp;gt;, принадлежащих увеличивающему пути &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt;, таких что &amp;lt;tex&amp;gt;c_f(p) = c_f(u,v)&amp;lt;/tex&amp;gt;. Назовем данные ребра критическими. Покажем, что каждое из &amp;lt;tex&amp;gt;|E|&amp;lt;/tex&amp;gt; ребер может становиться критическим не более, чем &amp;lt;tex&amp;gt;|V| - 1&amp;lt;/tex&amp;gt; раз. Заметим, что после увеличения потока вдоль пути &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; все критические ребра исчезают из остаточной сети, кроме того по определению остаточной пропускной способности пути хотя бы одно ребро увеличивающего пути {{---}} критическое.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим две вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; принадлежащие &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt;, соединенные некоторым ребром из &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt;. Увеличение производится вдоль кратчайших путей, поэтому если ребро &amp;lt;tex&amp;gt;(u,v)&amp;lt;/tex&amp;gt; становиться критическим в первый раз, верно, что &amp;lt;tex&amp;gt;\delta_f(s,v) = \delta_f(s,u) + 1&amp;lt;/tex&amp;gt;. После увеличения потока ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; исчезает из сети. Оно не появится в другом увеличивающем пути до тех, пор пока не будет уменьшен по обратному ребру &amp;lt;tex&amp;gt;(v, u)&amp;lt;/tex&amp;gt;. Это может произойти только в том случае, если ребро &amp;lt;tex&amp;gt;(v, u)&amp;lt;/tex&amp;gt; встретится на некотором увеличивающем пути. Пусть в момент перед увеличением поток в сети &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; составлял &amp;lt;tex&amp;gt;f'&amp;lt;/tex&amp;gt;, то поскольку увеличение производиться вдоль кратчайших путей, верно: &amp;lt;tex&amp;gt;\delta'_f(s,u) = \delta'_f(s, v) + 1&amp;lt;/tex&amp;gt;. Согласно [[#lemma1|лемме]] &amp;lt;tex&amp;gt;\delta_f(s,v) \le \delta'_f(s,v)&amp;lt;/tex&amp;gt;, откуда &amp;lt;tex&amp;gt;\delta'_f(s,u) = \delta'(s,v) + 1 \ge \delta_f(s,v) + 1 = \delta_f(s,u) + 2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итак в промежуток времени между тем, когда ребро &amp;lt;tex&amp;gt;(u,v)&amp;lt;/tex&amp;gt; становится критическим в первый раз, до момента, когда оно становится критическим в следующий раз, расстояние от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; увеличивается минимум на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Расстояние &amp;lt;tex&amp;gt;\delta(s,u)&amp;lt;/tex&amp;gt; в начальный момент времени больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;. Среди промежуточных вершин на кратчайшем пути &amp;lt;tex&amp;gt;s \leadsto u&amp;lt;/tex&amp;gt; не могут находиться &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Следовательно к тому моменту, когда вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; станет недостижимой из источника расстояние до нее не превысит &amp;lt;tex&amp;gt;|V| - 2&amp;lt;/tex&amp;gt;. Получаем, что ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; могло стать критическим не более &amp;lt;tex&amp;gt;(|V| -2)/2 = |V|/2 - 1&amp;lt;/tex&amp;gt; раз. Поскольку в графе не более &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt; пар вершин, между которыми могут существовать ребра в остаточной сети, то общее количество критических ребер в ходе выполнения алгоритма Эдмондса-Карпа равно &amp;lt;tex&amp;gt;O(V E)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Так как каждый увеличивающий путь содержит по крайней мере одно критическое ребро, следовательно число кратчайших путей составляет &amp;lt;tex&amp;gt;O(V E)&amp;lt;/tex&amp;gt;. На каждой итерации цикла '''while''' рассматривается ровно один увеличивающий путь, а поскольку в случае отсутствия такого пути выполнение цикла прерывается, то число итераций цикла '''while''' также составляет &amp;lt;tex&amp;gt;O(V E)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Если увеличивающий путь находить поиском в ширину, то каждую итерацию цикла '''while''' можно выполнить за время &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;. Инициализация в процедуре '''Edmonds_Karp''' производится за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, следовательно время работы алгоритма алгоритма Эдмондса-Карпа составляет &amp;lt;tex&amp;gt;O(V E^2)&amp;lt;/tex&amp;gt;. Заметим также, что сущетсвует сеть [http://community.topcoder.com/tc?module=Static&amp;amp;d1=tutorials&amp;amp;d2=maxFlowRevisited &amp;quot;грибок&amp;quot;] на которой нижняя граница времени работы алгоритмы Эдмондса-Карпа также составляет &amp;lt;tex&amp;gt;\Omega(V E^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Задача о максимальном потоке]]&lt;/div&gt;</summary>
		<author><name>93.92.200.173</name></author>	</entry>

	</feed>