Решение задачи K-подстроки с Codeforces
С пояснением   Просмотров: 1942
Назовем k-подстрокой строки s строку subs k = s k s k + 1..s n + 1 - k. очевидно, что subs 1 = s и существует ровно таких подстрок.
Назовём нечётным собственным супрефиксом строки T такую строку t, что выполняются следующие условия:
|T| > |t|;
|t| нечётно;
t является одновременно и префиксом, и суффиксом T.
Для каждой k-подстроки () s найдите наибольшую длину нечётного собственного супрефикса этой строки.
Пояснение к задаче
Рассмотрим супрефикс некоторой фиксированной k-подстроки: мы не можем подбирать бинарным поиском его максимальную длину, так как функция в общем случае не монотонная. Но если зафиксировать центр данного префикса, то, во-первых, однозначно зафиксируется центр соответствующего суффикса (если центром префикса является позиция i, то центром суффиска станет позиция n + 1 - i), а во-вторых, станет возможно искать его максимальную длину.
Таким образом, решение выглядит следующим образом: переберем центр префикса i и для фиксированного центра начнем бинарным искать максимальную длину 2x + 1 строки, такой, что ее центром является позиция i и она совпадает со строкой, центр которой находится в позиции n + 1 - i. Ответ ans i - x для i - x-подстроки тогда можно прорелаксировать значением 2x + 1. Также не забудем, что ответ ans i можно также улучшить значением ans i - 1 - 2.
Для сравнения подстрок на равенство предлагается для простоты использовать хэши. Для тех, кто не хочет полагаться на вероятность, сравнение можно проводить с помощью строковых структур данных (например стандартной связки Суффмасс + LСP + Sparse Table или суффдерева с LCA).
Замечание для любителей суффмассива: не стоит пренебрегать оптимизациями вида замены sort на stable_sort (сортировка слиянием) и break-а, если все суффиксы уже различны, они могут освободить вас от необходимости написания radix (или bucket) sort.
Автор: Администратор