Таблица инверсий
Пусть является перестановкой чисел .
| Определение: |
| Инверсией в перестановке называется всякая пара индексов такая, что и . |
| Определение: |
| Таблицей инверсий перестановки называют такую последовательность , в которой равно числу элементов перестановки , стоящих в левее числа и больших . |
Алгоритм построения
Таблицу инверсий тривиально построить по определению. Для каждого элемента перестановки считаем количество элементов, больших данного и стоящих в перестановке левее него. Алгоритм построения в псевдокоде выглядит так:
T[1..n] = 0
For i = 1..n
For j = 1..(i - 1)
if P[j] > P[i]
T[P[i]] = T[P[i]] + 1
Сложность данного алгоритма — . Уменьшить время работы можно используя дерево отрезков.
Получим из исходной перестановки обратную и запишем её в массив . Также заведём массив длиной , инициализированный нулями. После обработки -го элемента будем вносить значение 1 в ячейку . Обработку начинаем с последнего элемента и двигаемся к началу. Пусть, функция возвращает значение суммы элементов массива от 1 до . Тогда -й элемент таблицы инверсий находится так:
Данная формула даёт правильный ответ, так как содержит единицу только в том случае, если мы уже обработали элемент, стоящий в -й позиции. Так как обработка идёт от больших чисел к меньшим, выдаст нужное нам количество чисел, больших и стоящих в перестановке левее него.
Функция реализуется с помощью дерева отрезков. Каждое изменение массива и обращение к функции влечёт за собой операций. Таким образом получаем сложность алгоритма
Также существует достаточно простой алгоритм построения таблицы инверсий с использованием сортировки слиянием. Вначале выписываются следующие упорядоченные пары чисел: в -ой паре на первом месте стоит -й элемент перестановки, а на втором — 0. Далее применяется сортировка слиянием, при чем при выписывании элемента из второй цепочки упорядоченных пар, число на второй позиции в данном элементе увеличивается на количество элементов, оставшихся в первой цепочке. В конце сортировки получим цепочку упорядоченных пар. Выписывая вторые элементы данных упорядоченных пар, получим искомую таблицу инверсий. Сложность данного алгоритма совпадает со сложностью сортировки слиянием и составляет .
Алгоритм восстановления
Для восстановления таблицы перестановки из таблицы инверсий создаем таблицу, которую будем расширять, по мере добавления в неё чисел. Добавляем в эту таблицу число (где от до 1) на позицию , где - число в таблице инверсий на -том месте. Данный алгоритм довольно прост в реализации, но без использования дополнительных структур данных, имеет сложность , т. к. для вставки элемента в определённую позицию, требуется порядка перестановок элементов.
Приведём алгоритм восстановления с использованием сортировки слиянием, имеющий сложность .
Пусть и - цепочки упорядоченных пар целых неотрицательных чисел . Рассмотрим двоичную операцию , рекурсивно определенную на парах таких цепочек следующим образом:
$([m, n]\alpha)\circ([m', n']\beta)=\left\{\begin{aligned}[]
[m,n](\alpha \circ ([m'-m, n']\beta)), m \le m',\\
[m', n'](([m-m'-1, n]\alpha) \circ \beta), m>m'.\\
\end{aligned}
\right.$
Сопоставим каждому элементу таблицы инверсий его номер. Получится множество упорядоченных пар чисел , где — сам элемент, а — его номер. Разобьём данные элементы на пары и произведём с ними операцию . Получим некоторое количество цепочек упорядоченных пар. Также разбиваем их на пары и производим операцию . Так действуем, пока не останется одна цепочка. Выписывая вторые элементы данных упорядоченных пар в том порядке, в каком они представлены в цепочке, получим первоначальную перестановку.
Цепочка наподобие представляет "_ _ _ _ 4 _ 3 _ ", где "_" означает пропуск. Операция вставляет пропуски и заполнения из на место пропусков в .
Пример
- - таблица инверсий.
Получаем перестановку
Источники
- Д. Кнут - Искусство программирования, том 3.