668
правок
Изменения
→Описание алгоритма
=== Описание алгоритма ===
Пусть <tex>Z</tex>{{---}} функция хранится в массиве <tex>z[1..n],</tex> префикс-функцию будем записывать в массив <tex>p[1..n]</tex>.
Пойдем по массиву <tex>z</tex> слева направо, заметим, что если <tex>z[i] > 0, </tex> то для всех элементов с индексом <tex>i + j</tex>, где <tex>0 \leqslant j < z[i] </tex> значение <tex>p[i + j] </tex> будет не меньше, чем <tex>j + 1, </tex> в силу определения префикс и <tex>Z</tex> функции. Также заметим, что если мы уже установили значение в какое-то <tex>p[k]</tex> то менять уже не нужно, так как это только уменьшит значение <tex>p[k]</tex>. В итоге получаем алгоритм, : идем слева направо по массиву <tex>z</tex>. Пусть и пусть мы сейчас находимся на позиции <tex>i</tex> , тогда пытаемся записать в <tex>p</tex> от позиции <tex>i + z[i] - 1 </tex> до <tex>i</tex> значение <tex> j - i + 1,</tex> где <tex>j</tex> пробегает все значения <tex> 0.. z[i] - 1</tex>. В итоге каждый элемент в <tex>p</tex> будет просмотрен не более двух раз, откуда получаем асимптотику <tex>O(n).</tex>
=== Псевдокод ===