<?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=DAC</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=DAC"/>
		<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/DAC"/>
		<updated>2026-04-13T18:27:23Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_LCA_%D0%BA_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B5_RMQ&amp;diff=80916</id>
		<title>Сведение задачи LCA к задаче RMQ</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_LCA_%D0%BA_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B5_RMQ&amp;diff=80916"/>
				<updated>2021-05-29T14:48:52Z</updated>
		
		<summary type="html">&lt;p&gt;DAC: /* Препроцессинг */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Шаблон:Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дано корневое дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. На вход подаются запросы вида &amp;lt;tex&amp;gt;(u,\;v)&amp;lt;/tex&amp;gt;, для каждого запроса требуется найти их наименьшего общего предка.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение &lt;br /&gt;
|id=lca_suf_tree&lt;br /&gt;
|definition = '''Наименьшим общим предком''' (англ. ''least common ancestor'') двух узлов &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;T&amp;lt;/tex&amp;gt; называется узел &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;, который среди всех узлов, являющихся предками как узла &amp;lt;tex&amp;gt;u&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;
=== Идея ===&lt;br /&gt;
Будем решать задачу &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt;, уже умея решать задачу &amp;lt;tex&amp;gt;RMQ&amp;lt;/tex&amp;gt;. Тогда поиск наименьшего общего предка &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-того и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-того элементов сводится к запросу минимума на отрезке массива, который будет введен позднее.&lt;br /&gt;
&lt;br /&gt;
=== Препроцессинг ===&lt;br /&gt;
Для каждой вершины &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; определим глубину с помощью следующей рекурсивной формулы:&lt;br /&gt;
:&amp;lt;tex&amp;gt;\mathrm{depth}(u) = \begin{cases}&lt;br /&gt;
0 &amp;amp; u = \mathrm{root}(T),\\&lt;br /&gt;
\mathrm{depth}(v) + 1 &amp;amp; u = \mathrm{son}(v).&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
Ясно, что глубина вершины элементарным образом поддерживается во время обхода в глубину.&lt;br /&gt;
&lt;br /&gt;
Запустим [[Обход в глубину, цвета вершин|обход в глубину]] из корня, который будет вычислять значения следующих величин: &lt;br /&gt;
#Cписок глубин посещенных вершин &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Глубина текущей вершины добавляется в конец списка при входе в данную вершину, а также после каждого возвращения из её сына.&lt;br /&gt;
#Список посещений узлов &amp;lt;tex&amp;gt;\mathtt{vtx}&amp;lt;/tex&amp;gt;, строящийся аналогично предыдущему, только добавляется не глубина а сама вершина.&lt;br /&gt;
#Значение функции &amp;lt;tex&amp;gt;\mathtt{I}[u]&amp;lt;/tex&amp;gt;, возвращающей индекс в списке глубин &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, по которому была записана глубина вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; (например на момент входа в вершину).&lt;br /&gt;
&lt;br /&gt;
Вот таким образом будут выглядеть эти три массива после обхода в глубину:&lt;br /&gt;
&lt;br /&gt;
[[Файл:HoD8KSiOzTg.jpg‎ | мини | left | 700x500px| Пример массива &amp;lt;tex&amp;gt;\mathtt{vtx}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запрос ===&lt;br /&gt;
Будем считать, что &amp;lt;tex&amp;gt;\mathrm{rmq}(d,l,r)&amp;lt;/tex&amp;gt; возвращает индекс минимального элемента в &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; на отрезке &amp;lt;tex&amp;gt;[l..r]&amp;lt;/tex&amp;gt;. Тогда ответом на запрос &amp;lt;tex&amp;gt;\mathrm{lca}(u, v)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mathtt{I}[u] \leqslant \mathtt{I}[v]&amp;lt;/tex&amp;gt;, будет &amp;lt;tex&amp;gt;\mathtt{vtx}[\mathrm{rmq}(d,\mathtt{I}[u], \mathtt{I}[v])]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Доказательство корректности алгоритма ===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Наименьшему общему предку вершин &amp;lt;tex&amp;gt;u, v&amp;lt;/tex&amp;gt; соответствует минимальная глубина на отрезке &amp;lt;tex&amp;gt;d[\mathtt{I}[u], \mathtt{I}[v]]&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;T&amp;lt;/tex&amp;gt;. Рассмотрим отрезок &amp;lt;tex&amp;gt;d[\mathtt{I}[u]..\mathtt{I}[v]]&amp;lt;/tex&amp;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;w&amp;lt;/tex&amp;gt; (в дереве есть только один простой путь между вершинами), а следовательно минимум на отрезке никак не больше глубины &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Заметим, что в момент добавления &amp;lt;tex&amp;gt;\mathtt{I}[u]&amp;lt;/tex&amp;gt; обход посещал поддерево с корнем &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. В момент добавления &amp;lt;tex&amp;gt;\mathtt{I}[v]&amp;lt;/tex&amp;gt; мы все еще в поддереве с корнем &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Значит, и на отрезке между &amp;lt;tex&amp;gt;\mathtt{I}[u]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathtt{I}[v]&amp;lt;/tex&amp;gt; мы находились внутри поддерева с корнем &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Отсюда сделаем заключение, что на рассматриваемом отрезке не посещалась вершина, отличная от &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;, с глубиной меньшей либо равной глубины &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;, т. к. подобной вершины нет в поддереве с корнем &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
Рассмотрим дерево на рисунке 1. Найдем наименьшего общего предка вершин, помеченных красным цветом.&lt;br /&gt;
Список глубин, получающийся в результате обхода в глубину {{---}} &amp;lt;tex&amp;gt;[0, 1, 2, 1, 2, 1, 0, 1, 0].&amp;lt;/tex&amp;gt;&lt;br /&gt;
Глубина наименьшего общего предка красных вершин равна минимуму на отрезке &amp;lt;tex&amp;gt;[2, 1, 0, 1].&amp;lt;/tex&amp;gt;&lt;br /&gt;
[[Файл:Lca to rmq.png(2).png|thumb|center|400x200px|Рисунок к примеру]]&lt;br /&gt;
&amp;lt;div style='clear:left;'&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сложность ==&lt;br /&gt;
&lt;br /&gt;
Для нахождения минимального элемента на отрезке можно использовать [[Алгоритм Фарака-Колтона и Бендера|алгоритм Фарака-Колтона и Бендера]] для &amp;lt;tex&amp;gt;\pm 1RMQ&amp;lt;/tex&amp;gt;, т. к. соседние элементы в списке глубин отличаются не более чем на единицу. Длина списка глубин составляет &amp;lt;tex&amp;gt;(2n - 1)&amp;lt;/tex&amp;gt;, таким образом, препроцессинг работает за &amp;lt;tex&amp;gt;O(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;
*[[Решение RMQ с помощью разреженной таблицы]]&lt;br /&gt;
*[[Алгоритм Фарака-Колтона и Бендера]]&lt;br /&gt;
*[[Сведение задачи RMQ к задаче LCA]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
*[http://e-maxx.ru/algo/lca Наименьший общий предок. Нахождение за O (sqrt (N)) и O (log N) с препроцессингом O (N)]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Задача о наименьшем общем предке]]&lt;/div&gt;</summary>
		<author><name>DAC</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:HoD8KSiOzTg.jpg&amp;diff=80915</id>
		<title>Файл:HoD8KSiOzTg.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:HoD8KSiOzTg.jpg&amp;diff=80915"/>
				<updated>2021-05-29T14:43:00Z</updated>
		
		<summary type="html">&lt;p&gt;DAC: иллюстрация к статье &amp;quot;Сведение задачи LCA к задаче RMQ&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;иллюстрация к статье &amp;quot;Сведение задачи LCA к задаче RMQ&amp;quot;&lt;/div&gt;</summary>
		<author><name>DAC</name></author>	</entry>

	</feed>