День 6. Укконен.
- С++
- Битовое сжатие внутри структуры
- pragma pack
- sizeof от массива, указателя, вектора
- Сжатый бор
- Хранение: на ребре написано подстрока
- Хранение: или
struct Node { Edge next[26]; };
, или struct Node { Edge e; int next[26]; };
- Суффдерево. Построение суффдерева за квадрат.
- Задачи
- Число различных подстрок за O(n)
- Максимальный рефрен (len*count) за O(n)
- Вхождение строки в текст, и число вхождений, и первое, и последнее
- Общая подстрока двух строк
- LZSS
- Связь дерева и массива
- Дерево → массив+LCP за O(n)
- Массив+LCP → дерево за O(n)
- Укконен
- Онлайн, строка растёт s → sa
- Версия за квадрат: храним концы всех суффиксов
- Первая оптимизация: листья растут сами
- Главная идея: первым разветвится самый длинный не разветвившийся суффикс
- Текущая версия алгоритма: помним ссылку на позицию в боре самого длинного суффикса. Как только он разветвился, создали бесконечный лист и за O(n) нашли позицию следующего суффикса.
- Как быстро находить следующий суффикс? Суффссылка от отца + спуск.
- Вычисление суффссылки новой вершины.
- Доказательство линейности времени работы.
- Тонкости реализации: фиктивная вершина, разбор всех случаев во время спуска, создание суффссылки на ещё не существующую вершину.
- Примеры: aaaaab, ababbabaac