Алгоритм Шибера-Вишкина — различия между версиями
(→Обработка запроса) |
|||
Строка 66: | Строка 66: | ||
Чтобы получить из отрезка число, кратное <tex>2^l</tex>, будучи уверенными, что оно там есть, достаточно обнулить <tex>l</tex> битов в правой границе отрезка. | Чтобы получить из отрезка число, кратное <tex>2^l</tex>, будучи уверенными, что оно там есть, достаточно обнулить <tex>l</tex> битов в правой границе отрезка. | ||
}} | }} | ||
+ | |||
+ | Каждое значение <tex>\operatorname{inlabel} v</tex> соответствует вершине в полном двоичном дереве высоты <tex>h=\lceil\log_2 n\rceil</tex>. В двоичном дереве будем нумеровать вершины в инфиксном порядке: обойдем левое поддерево, занумеруем вершину, обойдем правое поддерево. В двоичном дереве будет ребро между вершинами <tex>\operatorname{inlabel} v</tex> и <tex>\operatorname{inlabel} u</tex>, если в начальном дереве есть ребро <tex>v\to u</tex>. Стандартных для двоичного дерева | ||
+ | ребер не будет. Они нужны только для того, чтобы занумеровать вершины и для следующего утверждения. | ||
+ | |||
+ | {{Утверждение | ||
+ | |statement=Если в начальном дереве есть ребро <tex>v\to u</tex> (<tex>u \in S(v)</tex>), то в построенном двоичном дереве | ||
+ | <tex>\operatorname{inorder} u \in S(\operatorname{inorder} v)</tex> | ||
+ | |proof= | ||
+ | }} | ||
+ | |||
+ | Посчитаем для каждого <tex>\operatorname{inlabel} v</tex> множество всех его потомков в двоичном дереве. Заметим, что | ||
+ | для хранения одного потомка достаточно хранить только его высоту в дереве. Чтобы восстановить его значение, нужно | ||
+ | просто подняться на <tex>\Delta h</tex> вверх от вершины <tex>v</tex>. Поэтому, все это множество можно уместить в | ||
+ | число: <tex>i</tex>-й бит будет единицей, если есть потомок на высоте <tex>i</tex>. Назовем это число <tex>\operatorname{ascendant} v</tex>. | ||
+ | |||
+ | В дальнейшем <tex>\operatorname{ascendant} v </tex> поможет в поиске <tex>LCA(\operatorname{inlabel} v, \operatorname{inlabel} u</tex>. Также, нам понадобится еще следующая информация. <tex>\operatorname{head} v</tex> {{---}} самая не глубокая вершина <tex>u</tex> такая, что <tex>\operatorname{inlabel} v = \operatorname{inlabel} u</tex>. | ||
==Обработка запроса== | ==Обработка запроса== |
Версия 01:26, 22 июня 2012
Алгоритм Шибера-Вишкина применяется для нахождения наименьшего общего предка двух вершин в дереве. Он использует
времени на подготовку и затем отвечает на каждый запрос за .Идея алгоритма
Основная идея алгоритма следующая.
- Если бы дерево, в котором нужно искать было бы цепочкой, можно было бы найти просто взяв ту вершину, которая находится в дереве выше.
- Если дерево — полное двоичное дерево высоты , то можно сопоставить каждой вершине битовый вектор длиной (целое число от до ) и с помощью битовых операций над этими векторами найти
Тогда, представив данное дерево как полное двоичное дерево, в каждой вершине которого находится цепочка, можно научиться искать
в нем за .Подготовка
Перенумеруем вершины в порядке префиксного обхода дерева: сначала обрабатывается текущая вершина, затем — поддеревья. Пусть
— такой порядок обхода.Обозначим за
количество вершин в поддереве вершины . Здесь и далее считаем, что вершина является и своим предком, и своим потомком.Утверждение: |
Пусть — вершина из поддерева . Тогда
|
По определению , вершин из поддерева образуют отрезок натуральных чисел длиной . Так как этот отрезок начинается с , то — отрезок . |
Покроем дерево путями. А именно, сопоставим каждой вершине
число такое, что прообраз каждого в связен и является простым путем от какой-то вершины вниз до листа.Утверждение: |
В качестве можно выбрать , кратное максимальной степени двойки, где . |
Пусть , — максимально. Пусть есть вершина такая, что . Так как в отрезке, соответствующем вершине есть два числа, кратных , то там есть и число, кратное . Но тогда выбран неверно. Значит, в поддереве есть только одна такая вершина , что .Рассмотрим два случая. Первый случай Других таких вершин , что дает такую же степень двойки, нет. Значит, во всех поддеревьях значения отличаются от .Второй случай Так как в поддереве , представлены все -ы из отрезка , то рассмотрим того потомка вершины , что . Тогда, так как степень двойки у максимальна, по утверждению в начале доказательства, других вершин с такой же степенью двойки нет, то . Так как отрезки, соответствующие поддеревьям сыновей, не пересекаются, не найдется другого — потомок , что в поддереве есть вершина с такой же степенью двойки. Значит, все вершины , у которых находятся в поддереве . Проведя аналогичное доказательство для , получим требуемое. |
Утверждение: |
, где |
Посмотрим на . Посмотрим на позицию самой правой единицы в .Так как в там еще , а в — уже единица, то в отрезке есть число, кратное .Докажем, что нет чисел, кратных . Пусть такое число нашлось. Тогда -й бит менялся хотя бы два раза, а значит, менялся -й бит. А значит, самый значащий отличающийся бит в и в больше, чем -й.Заметим, что функция просто выделяет номер самого значашего единичного бита.Функция Чтобы получить из отрезка число, кратное обнуляет все биты младше -го. , будучи уверенными, что оно там есть, достаточно обнулить битов в правой границе отрезка. |
Каждое значение
соответствует вершине в полном двоичном дереве высоты . В двоичном дереве будем нумеровать вершины в инфиксном порядке: обойдем левое поддерево, занумеруем вершину, обойдем правое поддерево. В двоичном дереве будет ребро между вершинами и , если в начальном дереве есть ребро . Стандартных для двоичного дерева ребер не будет. Они нужны только для того, чтобы занумеровать вершины и для следующего утверждения.Утверждение: |
Если в начальном дереве есть ребро ( ), то в построенном двоичном дереве
|
Посчитаем для каждого
множество всех его потомков в двоичном дереве. Заметим, что для хранения одного потомка достаточно хранить только его высоту в дереве. Чтобы восстановить его значение, нужно просто подняться на вверх от вершины . Поэтому, все это множество можно уместить в число: -й бит будет единицей, если есть потомок на высоте . Назовем это число .В дальнейшем
поможет в поиске . Также, нам понадобится еще следующая информация. — самая не глубокая вершина такая, что .Обработка запроса
Пусть
, — вершины в исходном дереве которых необходимо найти. Если , то они принадлежат одному простому пути, а следовательно ответом на запрос является , если , и , в противном случае. Теперь рассмотрим случай, когда , то есть и принадлежат разным простым путям. Найдем .Утверждение: |
, где |
Пусть | — индекс самой правой единицы в двоичном представлении . Из того, что общий предок и в полном двоичном дереве следует, что левых бит, совпадающих в и , должны быть такими же и в , а так как наименьший общий предок, то — минимальный такой индекс. То есть самый левый бит, в котором различаются и . А двоичное представление состоит из левых бит (или ), единички и нулей.