211
правок
Изменения
→Описание алгоритма
Далее, пусть мы выполнили <tex>k-1-</tex>ю фазу (т.е. вычислили значения массивов <tex>p</tex> и <tex>c</tex> для неё). Научимся за <tex>O(n)</tex> выполнять следующую, <tex>k-</tex>ю, фазу. Поскольку фаз всего <tex>O(\log n)</tex>, это даст нам требуемый алгоритм с временем <tex>O(n \log n)</tex>.
Заметим, что циклическая подстрока длины <tex>2^k</tex> состоит из двух подстрок длины <tex>2^{k-1}</tex>, которые мы можем сравнивать между собой за <tex>O(1)</tex>, используя информацию с предыдущей фазы — номера классов эквивалентности <tex>c</tex>. Таким образом, для подстроки длины <tex>2^k</tex>, начинающейся в позиции <tex>i</tex>, вся необходимая информация содержится в паре чисел <tex>(c[i], c[i + 2^{k-1}])</tex>.
Это даёт нам весьма простое решение: отсортировать подстроки длины <tex>2^k</tex> просто по этим парам чисел, это и даст нам требуемый порядок, т.е. массив <tex>p</tex>. Воспользуемся здесь приёмом, на котором основана цифровая сортировка: чтобы отсортировать пары, отсортируем их сначала по вторым элементам, а затем — по первым элементам (обязательно стабильной сортировкой). Однако отдельно вторые элементы уже упорядочены — этот порядок задан в массиве от предыдущей фазы. Тогда, чтобы упорядочить пары по вторым элементам, надо просто от каждого элемента массива <tex>p</tex> отнять <tex>2^{k-1}</tex> — это даст нам порядок сортировки пар по вторым элементам (<tex>p</tex> даёт упорядочение подстрок длины <tex>2^{k-1}</tex>, и при переходе к строке вдвое большей длины эти подстроки становятся их вторыми половинками, поэтому от позиции второй половинки отнимается длина первой половинки).