<?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=94.29.7.239&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=94.29.7.239&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/94.29.7.239"/>
		<updated>2026-04-08T13:46:11Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<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%A8%D0%B8%D0%B1%D0%B5%D1%80%D0%B0-%D0%92%D0%B8%D1%88%D0%BA%D0%B8%D0%BD%D0%B0&amp;diff=82645</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%A8%D0%B8%D0%B1%D0%B5%D1%80%D0%B0-%D0%92%D0%B8%D1%88%D0%BA%D0%B8%D0%BD%D0%B0&amp;diff=82645"/>
				<updated>2022-07-04T15:16:38Z</updated>
		
		<summary type="html">&lt;p&gt;94.29.7.239: Исправлены некоторые ошибки, сделал так, как в оригинальной статье&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Алгоритм Шибера-Вишкина''' (англ.''Schieber-Vishkin '') применяется для нахождения [[Сведение задачи LCA к задаче RMQ|наименьшего общего предка]] двух вершин в дереве.&lt;br /&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;
&lt;br /&gt;
# Если бы дерево, в котором нужно искать &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt; было бы простым путем, можно было бы найти &amp;lt;tex&amp;gt;LCA(u, v)&amp;lt;/tex&amp;gt; просто взяв ту вершину, которая находится в дереве ближе к корню.&lt;br /&gt;
# Если дерево {{---}} полное [[Дерево поиска, наивная реализация|двоичное дерево]],  высоты &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;, то можно сопоставить каждой вершине битовый вектор длиной &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; (целое число от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;2^h-1&amp;lt;/tex&amp;gt;) и с помощью битовых операций над этими векторами найти &amp;lt;tex&amp;gt;LCA(u, v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, представив данное дерево как полное [[Дерево поиска, наивная реализация|двоичное дерево]], в некоторых вершинах которого находится простой путь, можно научиться искать &amp;lt;tex&amp;gt;LCA(v, u)&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;
&lt;br /&gt;
&amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; {{---}} входное дерево с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами. Для него нужно отвечать на запросы &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} полное [[Дерево поиска, наивная реализация|двоичное дерево]]  с не менее, чем &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами. Будет введено и объяснено дальше.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;S(v)&amp;lt;/tex&amp;gt; {{---}} поддерево вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;. Здесь и далее считаем, что вершина является и своим предком, и своим потомком.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; ''выше'' &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; {{---}} то же самое, что &amp;lt;tex&amp;gt;u \in S(v)&amp;lt;/tex&amp;gt;. Корень выше любой вершины.&lt;br /&gt;
&lt;br /&gt;
Перенумеруем вершины в порядке [[Дерево поиска, наивная реализация|префиксного обхода дерева]]. Обозначим за &amp;lt;tex&amp;gt;\operatorname{size} 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;
|statement=Пусть &amp;lt;tex&amp;gt;u \in S(v)&amp;lt;/tex&amp;gt;. Тогда &lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{preOrder} u \in [\operatorname{preOrder} v; \operatorname{preOrder}v + \operatorname{size} v - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
По определению &amp;lt;tex&amp;gt;\operatorname{preOrder}&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\operatorname{preOrder} u&amp;lt;/tex&amp;gt; вершин из поддерева &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; образуют &lt;br /&gt;
отрезок натуральных чисел длиной &amp;lt;tex&amp;gt;\operatorname{size} v - 1&amp;lt;/tex&amp;gt;. Так как этот отрезок начинается с &lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{preOrder}v + 1&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\operatorname{preOrder} u&amp;lt;/tex&amp;gt; лежит в отрезке &amp;lt;tex&amp;gt;[\operatorname{preOrder} v; \operatorname{preOrder} v + \operatorname{size} v - 1]&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;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; такое, что прообраз каждого &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; связен и является простым путем от какой-то вершины вниз до листа.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=В качестве &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; можно выбрать &amp;lt;tex&amp;gt;\operatorname{preOrder} u&amp;lt;/tex&amp;gt;, кратное максимальной степени двойки, где &amp;lt;tex&amp;gt;u \in S(v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\operatorname{inlabel} v = \operatorname{preOrder} u = k2^b&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; {{---}} максимально.&lt;br /&gt;
Пусть есть вершина &amp;lt;tex&amp;gt;u' \in S(v)&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\operatorname{preOrder} u' = k'2^b&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Так как в отрезке, соответствующем вершине &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; есть два числа, кратных &amp;lt;tex&amp;gt;2^b&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
там есть и число, кратное &amp;lt;tex&amp;gt;2^{b+1}&amp;lt;/tex&amp;gt;. Но тогда &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; выбран неверно.&lt;br /&gt;
Значит, в поддереве &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; есть только одна такая вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;2^{max} | \operatorname{preOrder} u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая. &lt;br /&gt;
&lt;br /&gt;
'''Первый случай''': &amp;lt;tex&amp;gt;\operatorname{inlabel} v = \operatorname{preOrder} v&amp;lt;/tex&amp;gt;.&amp;amp;nbsp; Других таких вершин &amp;lt;tex&amp;gt;u'&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;u'&amp;lt;/tex&amp;gt; дает такую же степень двойки, нет.&lt;br /&gt;
Значит, во всех поддеревьях &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; значения &amp;lt;tex&amp;gt;\operatorname{inlabel}&amp;lt;/tex&amp;gt; отличаются&lt;br /&gt;
от &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Второй случай''': &amp;lt;tex&amp;gt;\operatorname{inlabel} v = \operatorname{preOrder} u&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;u \in S(v), u \ne v&amp;lt;/tex&amp;gt;. Так как в поддереве &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; представлены все &amp;lt;tex&amp;gt;\operatorname{preOrder}&amp;lt;/tex&amp;gt;-ы из отрезка &amp;lt;tex&amp;gt;[\operatorname{preOrder} v; \operatorname{preOrder} v + \operatorname{size} v - 1]&amp;lt;/tex&amp;gt;, то рассмотрим того непосредственного потомка &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, что &amp;lt;tex&amp;gt;u \in S(w)&amp;lt;/tex&amp;gt;. Тогда, так как степень двойки у &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; максимальна, по утверждению в начале доказательства, других вершин с такой же степенью двойки нет, то &amp;lt;tex&amp;gt;\operatorname{inlabel} w = \operatorname{inlabel} v = \operatorname{preOrder} u&amp;lt;/tex&amp;gt;. Так как отрезки, соответствующие поддеревьям сыновей, не пересекаются, не найдется другого &amp;lt;tex&amp;gt;w'&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;v'&amp;lt;/tex&amp;gt;, у которых &amp;lt;tex&amp;gt;\operatorname{inlabel} v' = \operatorname{inlabel} v&amp;lt;/tex&amp;gt; находятся в поддереве &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Получили, что прообраз &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; в вершине &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; или обрывается, или продолжается вниз ровно в одного потомка. Значит, прообраз &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; {{---}} простой путь из какой-то вершины вниз в &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, что и требовалось доказать.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\operatorname{inlabel} v = 2^i \bigg\lfloor \dfrac{\operatorname{preOrder} v + \operatorname{size} v}{2^i}\bigg\rfloor&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i = \lfloor\log_2 ((\operatorname{preOrder} - 1) \oplus (\operatorname{preOrder} v + \operatorname{size} v - 1)) \rfloor&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Посмотрим на &amp;lt;tex&amp;gt;A = (\operatorname{preOrder} v - 1) \oplus (\operatorname{preOrder} v + \operatorname{size} v - 1)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Посмотрим на позицию самого значимого единичного бита &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Так как в &amp;lt;tex&amp;gt;\operatorname{preOrder} v - 1&amp;lt;/tex&amp;gt; там еще &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;\operatorname{preOrder} v + \operatorname{size} v - 1&amp;lt;/tex&amp;gt; {{---}} уже единица, то в отрезке &amp;lt;tex&amp;gt;[\operatorname{preOrder} v; \operatorname{preOrder} v + \operatorname{size} v]&amp;lt;/tex&amp;gt; есть число, кратное &amp;lt;tex&amp;gt;2^l&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Докажем, что нет чисел, кратных &amp;lt;tex&amp;gt;2^{l+1}&amp;lt;/tex&amp;gt;. Пусть такое число нашлось. Тогда &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;-й бит менялся хотя бы два раза, а значит, менялся &lt;br /&gt;
&amp;lt;tex&amp;gt;l+1&amp;lt;/tex&amp;gt;-й бит. А значит, самый значащий отличающийся бит в &amp;lt;tex&amp;gt;\operatorname{preOrder} v - 1&amp;lt;/tex&amp;gt; и в &amp;lt;tex&amp;gt;\operatorname{preOrder} v + \operatorname{size} v - 1&amp;lt;/tex&amp;gt; больше, чем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;-й.&lt;br /&gt;
&lt;br /&gt;
Заметим, что функция &amp;lt;tex&amp;gt;\lfloor \log_2 a \rfloor + 1&amp;lt;/tex&amp;gt; просто выделяет номер самого значашего единичного бита.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;2^l\left\lfloor\dfrac{a}{2^l}\right\rfloor&amp;lt;/tex&amp;gt; обнуляет все биты младше &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;-го. &lt;br /&gt;
&lt;br /&gt;
Чтобы получить из отрезка число, кратное &amp;lt;tex&amp;gt;2^l&amp;lt;/tex&amp;gt;, будучи уверенными, что оно там есть, достаточно обнулить &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; битов в правой границе отрезка.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Каждое значение &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; соответствует вершине в полном двоичном дереве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; высоты &amp;lt;tex&amp;gt;h=\lceil\log_2 n\rceil&amp;lt;/tex&amp;gt;. В дереве на одном наборе вершин будет построено два набора ребер: ''каркасные'' и ''основные''. Для каждой вершины &amp;lt;tex&amp;gt;v \in V(B)&amp;lt;/tex&amp;gt; с уровня, кроме последнего, будут каркасные ребра &amp;lt;tex&amp;gt;v\to2v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v\to2v+1&amp;lt;/tex&amp;gt;. Таким образом, вершины в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;  будут занумерованы в инфиксном порядке обхода по каркасным ребрам: сначала обрабатывается левое поддерево, потом {{---}} вершина, потом {{---}} правое поддерево. В &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; будет основное ребро между вершинами &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{inlabel} u&amp;lt;/tex&amp;gt;, если в &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; есть ребро &amp;lt;tex&amp;gt;v\to u&amp;lt;/tex&amp;gt;. Корень имеет номер &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Будем говорить, что вершина &amp;lt;tex&amp;gt;u \in B&amp;lt;/tex&amp;gt; лежит в поддереве вершины &amp;lt;tex&amp;gt;u \in B&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;u \in S(v)&amp;lt;/tex&amp;gt;), если от &amp;lt;tex&amp;gt;v&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;
|statement=Если в &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; есть ребро &amp;lt;tex&amp;gt;v\to u&amp;lt;/tex&amp;gt;, то в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\operatorname{inlabel} u \in S(\operatorname{inlabel} v)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Другими словами, все основные ребра направлены вниз.&lt;br /&gt;
|proof=&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Посчитаем для каждого &amp;lt;tex&amp;gt;\operatorname{inlabel} v&amp;lt;/tex&amp;gt; множество всех его предков в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; по основным ребрам. Заметим, что для хранения одного предка достаточно хранить только его высоту в дереве. Чтобы восстановить его значение, нужно просто подняться на &amp;lt;tex&amp;gt;\Delta h&amp;lt;/tex&amp;gt; вверх от вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;. Поэтому, все это множество можно уместить в целое число: &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й бит будет единицей, если есть предок на высоте &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Назовем это число, отвечающее множеству предков, &amp;lt;tex&amp;gt;\operatorname{ascendant} v&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В дальнейшем &amp;lt;tex&amp;gt;\operatorname{ascendant} v &amp;lt;/tex&amp;gt; поможет в поиске &amp;lt;tex&amp;gt;LCA(\operatorname{inlabel} v, \operatorname{inlabel} u)&amp;lt;/tex&amp;gt;. Также, нам понадобится еще следующая информация. &amp;lt;tex&amp;gt;\operatorname{head} v&amp;lt;/tex&amp;gt; {{---}} самая не глубокая вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\operatorname{inlabel} v = \operatorname{inlabel} u&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;\operatorname{level} v&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;.&lt;br /&gt;
&lt;br /&gt;
==Обработка запроса==&lt;br /&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;LCA&amp;lt;/tex&amp;gt; которых необходимо найти. Если &amp;lt;tex&amp;gt;\operatorname{inlabel} x = \operatorname{inlabel} y&amp;lt;/tex&amp;gt;, то они принадлежат одному простому пути, а следовательно ответом на запрос является &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;\operatorname{level} x \leqslant \operatorname{level} y&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, в противном случае. Теперь рассмотрим случай, когда &amp;lt;tex&amp;gt;\operatorname{inlabel} x \ne \operatorname{inlabel} 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; принадлежат разным простым путям. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Следующие вычисления позволяют найти &amp;lt;tex&amp;gt;\operatorname{inlabel} LCA(x,y)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
#&amp;lt;tex&amp;gt;i = \lfloor\log_2 (\operatorname{inlabel} x \oplus \operatorname{inlabel} y)\rfloor&amp;lt;/tex&amp;gt;&lt;br /&gt;
#&amp;lt;tex&amp;gt;path = 2^i \lfloor\dfrac{(\operatorname{ascendant} x) \wedge (\operatorname{ascendant} y)}{2^i}\rfloor&amp;lt;/tex&amp;gt;&lt;br /&gt;
#&amp;lt;tex&amp;gt;\operatorname{inlabel} LCA(x, y) = \lfloor\dfrac12(path \oplus (path - 1))\rfloor + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\operatorname{inlabel} x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{inlabel} y&amp;lt;/tex&amp;gt; {{---}} вершины в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Биты в их записи задают задают их местоположение в дереве.&lt;br /&gt;
Ноль {{---}} спуститься влево, единица {{---}} спуститься вправо или остаться здесь. Значит, наиболее значимый бит побитового исключающего или их номеров даст глубину, на которой пути до этих вершин начинают расходиться. Это и хранится в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значит, мы нашли &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt; по каркасным ребрам. Однако, могло случиться так, что &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt; по основным ребрам, поиском которого мы занимаемся, находится выше (он не может находиться ниже или в стороне, так как все основные ребра направлены вниз). &lt;br /&gt;
&lt;br /&gt;
Взяв побитовое и &amp;lt;tex&amp;gt;\operatorname{ascendant} x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{ascendant} y&amp;lt;/tex&amp;gt;, в старших единичных битах мы получим путь от корня по основным ребрам до этих вершин. При этом, про те биты, которые отвечают за уровни ниже &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt;, ничего не известно. Поэтому, нужно их обнулить. Умножение и деление на &amp;lt;tex&amp;gt;2^i&amp;lt;/tex&amp;gt; обнулят ненужные биты. После этого, для нахождения &amp;lt;tex&amp;gt;LCA&amp;lt;/tex&amp;gt; по основным ребрам, нужно найти в &amp;lt;tex&amp;gt;path&amp;lt;/tex&amp;gt; наименее значимый единичный бит. Формула &amp;lt;tex&amp;gt;\dfrac12(x \oplus (x - 1)) + 1&amp;lt;/tex&amp;gt; имеено это и делает.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
После этих действий нами был получен путь, в котором находится ответ. Осталось посмотреть на точки входа &lt;br /&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;\operatorname{inlabel} LCA(x, y)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Это можно сделать с помощью посчитанной функции &amp;lt;tex&amp;gt;\operatorname{head}&amp;lt;/tex&amp;gt;: найти &amp;lt;tex&amp;gt;\operatorname{head} 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;
==Оценка сложности==&lt;br /&gt;
===Построение===&lt;br /&gt;
Подсчет массивов &amp;lt;tex&amp;gt; \operatorname{inlabel} &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \operatorname{preOrder}&amp;lt;/tex&amp;gt; занимает &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; \operatorname{preOrder}&amp;lt;/tex&amp;gt; можно посчитать, например, [[Обход в глубину, цвета вершин|обходом в глубину]], а &amp;lt;tex&amp;gt; \operatorname{inlabel} &amp;lt;/tex&amp;gt; выражается через &amp;lt;tex&amp;gt; \operatorname{preOrder}&amp;lt;/tex&amp;gt;, как описано выше.&lt;br /&gt;
&lt;br /&gt;
===Запрос===&lt;br /&gt;
&amp;lt;tex&amp;gt;\operatorname{inlabel} LCA(x, y)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\operatorname{head} v'&amp;lt;/tex&amp;gt; вычисляются за &amp;lt;tex&amp;gt;O(1)&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;
*[[Алгоритм Тарьяна поиска LCA за O(1) в оффлайн ]]&lt;br /&gt;
*[[Метод двоичного подъема]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://ia600208.us.archive.org/12/items/onfindinglowe00schi/onfindinglowe00schi.pdf Baruch Schieber, Uzi Vishkin, &amp;quot;On Finding Lowest Common Ancestors: Simplification and Parallelization&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Задача о наименьшем общем предке]]&lt;/div&gt;</summary>
		<author><name>94.29.7.239</name></author>	</entry>

	</feed>