Таблица инверсий
Пусть перестановкой чисел .
является
Определение: |
Инверсией в перестановке | называется всякая пара индексов такая, что и .
Определение: |
Таблицей инверсий перестановки | называют такую последовательность , в которой равно числу элементов перестановки , стоящих в левее числа и больших .
Алгоритм построения
Таблицу инверсий тривиально построить по определению. Для каждого элемента перестановки считаем количество элементов, больших данного и стоящих в перестановке левее него. Алгоритм построения в псевдокоде выглядит так:
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.