Изменения

Перейти к: навигация, поиск

Level Ancestor problem

185 байт добавлено, 17:25, 15 мая 2019
Нет описания правки
найти предка вершины <tex>v</tex>, который находится на расстоянии <tex>k</tex> от корня дерева <tex>T</tex>.
}}
== Наивная реализация и двоичные подъемы ==
[[Файл:LevelAncestor.png|200px|thumb|right]]
Используя обход в глубину посчитаем глубину каждой вершины дерева (это можно сделать за <tex>O(n)</tex>), после чего можем из вершины <tex>v</tex> подняться до необходимой глубины вершины <tex>k</tex>,
что так же в худшем случае работает за <tex>O(n)</tex>.
Получили алгоритм за < <tex>O(n), O(n)</tex> > времени и <tex>O(n)</tex> памяти, где время ответа на
запрос можно улучшить до <tex>O(\log n)</tex> c помощью [[Метод двоичного подъёма | предподсчета двоичных подъемов]] ,
но тогда и время предподсчета в наивной реализации (посчитать подъемы для всех вершин) ухудшится до < <tex>O(n \log n),
O(\log n)</tex> > времени и <tex>O(n \log n)</tex> памяти. Альтернативой данным двум алгоритмам является полный предподсчет всех возможных запросов, что соответственно дает нам асимптотику < <tex>O(n^2), O(1)</tex> > времени и <tex>O(n^2)</tex> памяти.
 
В данном примере поступает запрос <tex>LA(v, 2)</tex>, на который алгоритм должен дать ответ <tex>h</tex>.
 
== Использование Heavy-light декомпозиции ==
Этот алгоритм базируется на различных способах [[Heavy-light декомпозиция | декомпозиции дерева]] (выберем heavy-light декомпозицию), из свойств этого разбиения следует,
В итоге полученный алгоритм действительно работает за < <tex>O(n), O(1)</tex> > времени и за <tex>O(n)</tex> памяти.
== Сравнение с наивными реализациями ==
[[Файл:LevelAncestor.png|200px|thumb|right]]
Используя обход в глубину посчитаем глубину каждой вершины дерева (это можно сделать за <tex>O(n)</tex>), после чего можем из вершины <tex>v</tex> подняться до необходимой глубины вершины <tex>k</tex>,
что так же в худшем случае работает за <tex>O(n)</tex>.
Получили алгоритм за < <tex>O(n), O(n)</tex> > времени и <tex>O(n)</tex> памяти, где время ответа на
запрос можно улучшить до <tex>O(\log n)</tex> c помощью [[Метод двоичного подъёма | предподсчета двоичных подъемов]] ,
но тогда и время предподсчета в наивной реализации (посчитать подъемы для всех вершин) ухудшится до < <tex>O(n \log n),
O(\log n)</tex> > времени и <tex>O(n \log n)</tex> памяти. Альтернативой данным двум алгоритмам является полный предподсчет всех возможных запросов, что соответственно дает нам асимптотику < <tex>O(n^2), O(1)</tex> > времени и <tex>O(n^2)</tex> памяти.
 
Таким образом самым оптимальным из описанных как по времени, так и по памяти является алгоритм Macro-Micro-Tree.
 
В данном примере поступает запрос <tex>LA(v, 2)</tex>, на который алгоритм должен дать ответ <tex>h</tex>.
== См. также ==
*[[Метод двоичного подъёма]]
Анонимный участник

Навигация