Level Ancestor problem — различия между версиями
Строка 20: | Строка 20: | ||
Данное разбиение можно строить за <tex>O(n)</tex>, что дает нам алгоритм за < <tex>O(n), O(\log n)</tex> >. | Данное разбиение можно строить за <tex>O(n)</tex>, что дает нам алгоритм за < <tex>O(n), O(\log n)</tex> >. | ||
== Алгоритм лестниц == | == Алгоритм лестниц == | ||
− | =Longest path decomposition= | + | === Longest path decomposition === |
Разобьем все вершины на пути следующим образом. Обойдем дерево с помощью обхода в глубину, пусть мы стоим в вершине | Разобьем все вершины на пути следующим образом. Обойдем дерево с помощью обхода в глубину, пусть мы стоим в вершине | ||
<tex>v</tex>, обойдем всех ее детей, добавив <tex>v</tex> в путь, идущий в самое глубокое поддерево, | <tex>v</tex>, обойдем всех ее детей, добавив <tex>v</tex> в путь, идущий в самое глубокое поддерево, | ||
т.е. в котором находится вершина с саомй большой глубиной. | т.е. в котором находится вершина с саомй большой глубиной. | ||
Для каждой вершины сохраним номер пути в который она входит. | Для каждой вершины сохраним номер пути в который она входит. | ||
− | =Ladder decomposition= | + | === Ladder decomposition === |
Увеличим каждый путь в два раза вверх, для каждого ового пути сохраним все входящие в него вершины, | Увеличим каждый путь в два раза вверх, для каждого ового пути сохраним все входящие в него вершины, | ||
а для каждой вершины сохраним ее номер в пути, в который она входит. Построение обычной longest-path декомпозиции займет у | а для каждой вершины сохраним ее номер в пути, в который она входит. Построение обычной longest-path декомпозиции займет у |
Версия 23:00, 11 мая 2019
Задача о уровне предка (англ. "Level Ancestor problem") является задачей о превращении данного корневого дерева T в структуру данных, которая сможет определить предка любого узла на заданном расстоянии от корня дерева.
Задача: |
Дано корневое дерево | c вершинами. Поступают запросы вида , для каждого из которых необходимо найти предка вершины , который находится на расстоянии от корня дерева .
Содержание
Наивная реализация и двоичные подъемы
Используя обход в глубину посчитаем глубину каждой вершины дерева (это можно сделать за предподсчета двоичных подъемов , но тогда и время предподсчета в наивной реализации (посчитать подъемы для всех вершин) ухудшится до < >. Альтернативой данным двум алгоритмам является полный предподсчет всех возможных запросов, что соответственно дает нам ассимптотику < >.
), после чего можем из вершины подняться до необходимой глубины вершины , что так же в худшем случае работает за . Получили алгоритм за < >, где время ответа на запрос можно улучшить до c помощьюВ данном примере поступает запрос
, на который алгоритм должен дать ответ h.Использование Heavy-light декомпозиции
Этот алгоритм базируется на различных способах декомпозиции дерева (выберем heavy-light декомпозицию), из свойств этого разбиения следует, что подняться на любую высоту из вершины мы можем за . Данное разбиение можно строить за , что дает нам алгоритм за < >.
Алгоритм лестниц
Longest path decomposition
Разобьем все вершины на пути следующим образом. Обойдем дерево с помощью обхода в глубину, пусть мы стоим в вершине
, обойдем всех ее детей, добавив в путь, идущий в самое глубокое поддерево, т.е. в котором находится вершина с саомй большой глубиной. Для каждой вершины сохраним номер пути в который она входит.Ladder decomposition
Увеличим каждый путь в два раза вверх, для каждого ового пути сохраним все входящие в него вершины, а для каждой вершины сохраним ее номер в пути, в который она входит. Построение обычной longest-path декомпозиции займет у нас O(n) времени (обход в глубину), соответственно удлиннение каждого пути ухудшит ассимптотику до
. После этого посчитаем двоичные подьемы для каждой вершины за , что соответственно не ухудшит ассимптотику.Пусть после этого нам пришел запрос
.