Тандемные повторы

Материал из Algocode wiki
Версия от 18:06, 19 ноября 2020; KiKoS (обсуждение | вклад) (Новая страница: «==Постановка задачи== Назовем `тандемным повтором` такую подстроку четной длины $S[i..j]$, чт...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Постановка задачи

Назовем `тандемным повтором` такую подстроку четной длины $S[i..j]$, что

$$S[i..\frac{i + j}{2}] = S[\frac{i + j}{2} + 1..j]$$

Наша задача --- найти самую длинную подстроку в строке S, которая является тандемным повтором.

Идея

Давайте воспользуемся методом Разделяй и властвуй. Будем делить строку пополам, искать ответ для левой и правой половины, после чего склеивать ответы обратно, находя число тандемных повторов, которые лежат и в левой, и в правой половине.

Теперь хочется за $O(n)$ найти самый длинный тандемный повтор, который пересекается центром. Давайте предположим, что центр разбивает правую половину тандема, а другой случай рассмотрим симметрично.

Переберем место, парное тому, где произошло разделение. А именно, если размер искомого тандемного повтора был $2d$, то переберем точку, находящуюся на расстоянии $d$ слева от центра. Назовем эту точку $j$, а самую левую точку тандемного повтора назовем $i$. Тогда у нас появилось разбиение на $S[i..j]$ и $S[j+1..i + d - 1]$. Заметим, что парные им блоки были слева и справа от разделителя разделяй-и-властвуй. То есть теперь нам надо проверить равенство каких-то подстрок $S$ и подстрок, которые границей примыкают к разделителю.

Z-функция

Чтобы оптимизировать последний шаг, воспользуемся z-функцией. А именно, чтобы сравнить левые части, заранее посчитаем z-функцию для левой половины строки, и будем смотреть, сколько символов совпало. Для сравнения правых частей тандема склеим строки $S[\frac{n}{2}..n]$ и $S[0..\frac{n}{2}-1]$. Насчитав z-функцию на них, мы получим нужное расстояние для позиции $j$. Останется только проверить, что сумма двух длин не меньше $d$. При нахождении максимального тандемного повтора это будет критерием на обновление $d_{max}$. Общая асимптотика $O(n \log n)$