Дерево палиндромов — различия между версиями
(→Построение) |
(→Построение) |
||
| Строка 34: | Строка 34: | ||
Будем также поддерживать максимальный палиндром-суффикс обработанного префикса <tex>p</tex>. Назовем его <tex>t</tex>. | Будем также поддерживать максимальный палиндром-суффикс обработанного префикса <tex>p</tex>. Назовем его <tex>t</tex>. | ||
| − | [[Файл: | + | [[Файл:palindromic_tree_nodes.png|border]] |
Т.к. <tex>t</tex> находится в уже обработанной части строки, то ему соответствует какая-то вершина в дереве. У этой вершины есть суффиксная ссылка на какую-то другую вершину, у которой тоже есть суффиксная ссылка и т.д. | Т.к. <tex>t</tex> находится в уже обработанной части строки, то ему соответствует какая-то вершина в дереве. У этой вершины есть суффиксная ссылка на какую-то другую вершину, у которой тоже есть суффиксная ссылка и т.д. | ||
Версия 19:25, 6 июня 2016
Дерево палиндромов — структура данных, позволяющая решить некоторые интересные задачи на палиндромы.
Эту структуру данных придумал Михаил Рубинчик и рассказал ее на летних сборах в Петрозаводске в 2014 году.
Содержание
Описание структуры
Дерево палиндромов состоит из вершин. Каждая вершина соответствует палиндрому. Через будем обозначать строку, которой соответствует вершина .
Ребра дерева палиндромов ориентированные и помечены символами. Ребро с символом из вершины в вершину означает, что . Тут означает конкатенацию строк.
Также в дереве палиндромов присутствуют суффиксные ссылки. Суффиксная ссылка из вершины ведет в вершину , если является наибольшим суффиксом строки .
Название структуры данных выбрано не совсем удачно, т.к. на самом деле она представляет из себя два дерева, однако суффиксные ссылки могут вести как в то же, так и в другое дерево. Это сделано для удобства реализации. Также в целях экономии памяти мы не будем хранить для каждой вершины соответствующую ей строку-палиндром. Вместо этого мы будем хранить только длину палиндрома.
Итак, у нас будет два дерева. Одно дерево для палиндромов четной длины, другое — для палиндромов нечетной длины. Каждое дерево будет иметь фиктивный корень. Обозначим корни четного и нечетного дерева соответственно и .
будет соответствовать фиктивному палиндрому длины -1. Это нужно для того, чтобы не обрабатывать отдельно случай добавления палиндрома длины 1. Теперь каждый раз при добавлении новой вершины к вершине мы будем просто указывать ее длину равной .
будет соответствовать фиктивному палиндрому длины 0.
Также направим суффиксные ссылки обоих корней к вершине . Это нужно для того, чтобы .
Построение
Будем обрабатывать строку символ за символом. Пусть мы уже обработали некоторый префикс и теперь хотим добавить следующий символ строки, назовем его .
Будем также поддерживать максимальный палиндром-суффикс обработанного префикса . Назовем его .
Т.к. находится в уже обработанной части строки, то ему соответствует какая-то вершина в дереве. У этой вершины есть суффиксная ссылка на какую-то другую вершину, у которой тоже есть суффиксная ссылка и т.д.



