Этот блог основан на задаче 1591D - Ещё одна задача на сортировку, надеюсь вам он понравится.
Базовые понятия
Для начала, разберемся в базовых понятиях, вы можете пропустить эту секцию, если все знаете.
Четность перестановки $$$p$$$ это четность количества инверсий в ней. Инверсия это пара $$$(i, j)$$$ такая, что $$$i < j, p_i > p_j$$$.
Композиция перестановок определяется так $$$(f \circ g)_x = f_{g_x}$$$, мы сначала применяем $$$g$$$, затем $$$f$$$.
Цикл это перестановка, где некоторые индексы циклически сдвинуты, например $$$p = \begin{pmatrix}1 & 5 & 2 & 4 & 3\end{pmatrix}$$$ это цикл $$$\begin{pmatrix}2 & 3 & 5\end{pmatrix}$$$.
Теорема. Любая перестановка это композиция непересекающихся циклов.
Доказательство. Посмотрим на граф с вершинами от $$$1$$$ до $$$n$$$, и ребрами $$$i \to p_i$$$ для всех $$$i$$$. Поскольку $$$p$$$ перестановка, входящая и исходящая степень любой вершины равна 1, значит наш граф это набор циклов, что и требовалось.
Лемма. Применяя транспозицию(меняя два элемента местами) мы меняем четность перестановки.
Эта лемма очень важна, поэтому остается в качестве упражнения читателю
Факт. Четность $$$(f \circ g)$$$ равна сумме четностей $$$f$$$ и $$$g$$$.
Доказательство. Применение транспозиции меняет четность, поэтому если $$$f$$$ представляется в виде $$$k$$$ транспозиции, то четность $$$k$$$ это четность $$$f$$$. Пусть $$$f$$$ представляется $$$k$$$ транспозициями, а $$$g$$$ представляется $$$m$$$ транспозициями, тогда $$$f \circ g$$$ может быть представлена как $$$k + m$$$ транспозиций, но четность $$$f \circ g$$$ это четность $$$k + m$$$, что в свою очередь является суммой чётностей $$$f$$$ и $$$g$$$, ЧТД.
Подсчёт числа инверсий и четности перестановки
Существует очень много способов посчитать количество инверсий за $$$O(n \log n)$$$.
Однако, существует простой способ посчитать четность перестановки, не считая напрямую количество инверсий.
Теорема. Перестановка представляется в виде композиции 3-циклов тогда и только тогда, когда она чётная.
Доказательство. 3-цикл чётный, поэтому композиция 3-циклов тоже четная. Осталось только доказать, что для четных перестановок такое представление существует.
Попробуем построить его итеративно, начиная с тождественной перестановки, последовательно применяя 3-циклы. На $$$i$$$-ой итерации мы предполагаем, что первые $$$i - 1$$$ элементов уже стоят на месте, и мы пытаемся поставить $$$i$$$-ый. Если $$$i$$$-ый элемент не на месте, то пусть в текущей перестановке он находится на месте $$$j$$$. Тогда $$$j > i$$$, и давайте применим цикл $$$n \to j \to i$$$, а если $$$j = n$$$, то $$$n - 1 \to j \to i$$$. Таким образом мы можем поставить на место $$$i$$$-ый элемент, и не нарушить расположение предыдущих.
Так мы можем сделать $$$n - 2$$$ шагов. Далее возможны две ситуации
Последние два элемента на месте, значит мы нашли искомое разбиение, и наша перестановка была чётной.
Последние два элемента не на месте, то есть они поменяны местами. Значит текущая перестановка отличается от нашей одной транспозицией, но текущая перестановка чётная, значит наша нечётная.
Ниже приведена реализация
Тем самым мы доказали теорему, и нашли простой алгоритм, позволяющий за $$$O(n)$$$ вычислить четность перестановки.
Excuse me, in the contest, I checked if there are even number of (even vertices cycles) then the answer would be "YES" which is the same as the parity of the permutation is even. But how to prove that they are actually the same?
Thanks.
Let's prove that the parity of $$$p \in S_n$$$ is the same as the parity of $$$n + cycles(p)$$$.
Let's do induction over all $$$p \in S_n$$$ on the number of inversions. If $$$p$$$ has $$$0$$$ inversions (base case), the condition trivially holds. If not, choose an arbitrary inversion $$$(i, i+1)$$$ and swap those elements (this effectively decreases the number of inversions by $$$1$$$). The number of cycles will either increase or decrease (so their parity changes) and so does the parity. Therefore induction holds.
As was mentioned above parity of $$$f \circ g$$$ is sum of parities of $$$f$$$ and $$$g$$$.
Note, that even length cycle is odd as permutation, and odd length cycle is even, because we can represent cycle length $$$L$$$ with $$$L - 1$$$ swaps. So if $$$f = C_1 \circ C_2 \circ \ldots \circ C_k$$$, and $$$m$$$ of them have even length, then $$$m$$$ of them are odd as permutations, so parity of $$$f$$$ is parity of $$$m$$$, that's exactly what you need.
And from this we can get, that parity of $$$f$$$ is $$$n + cycles(f)$$$. Indeed, if length of $$$C_i$$$ is $$$L_i$$$, then parity of $$$C_i$$$ is $$$L_i - 1$$$. Parity of $$$f$$$ is sum of parities over $$$C_i$$$, that is $$$(L_1 - 1) + (L_2 - 1) + \ldots + (L_k - 1)$$$, but sum of $$$L_i$$$ is $$$n$$$, so parity of $$$f$$$ is parity of $$$n - cycles(f)$$$, which is same as parity of $$$n + cycles(f)$$$
Are there any other problems similar to the one discussed above?
911D - Inversion Counting
987E - Petr and Permutations
https://codeforces.net/contest/1430/problem/E
hey man very intersting blog...are there any other resources where i can further read about thus stuff??
I am not able to prove the lemma..any hints ??? thematdev
Consider a permutation ________a_____b___________. Here we have to swap a and b. For now consider a > b (Similarly you can also prove for a<b).
Part1 = numbers appearing before a
Part2 = numbers appearing after a and before b
Part3 = numbers appearing after b
x2 = number of numbers less than b in part 2
y2 = number of numbers greater than b and less than a in part 2
z2 = number of numbers greater than a in part 2
x3 = number of numbers less than b in part 3
y3 = number of numbers greater than b and less than a in part 3
z3 = number of numbers greater than a in part 3
inversion count of a number 'k' is number of numbers < k coming after k
Now observe carefully, if we swap a and b, the change in number of inversions of whole permutation will be only due to change in numbers of inversions of sub-array a_______b.
By definition Inversion is pair (i,j) such that i<j, pi>pj. So before swaps number of inversion count of 'a' will be
n1 = x2 + y2 + x3 + y3 + 1
and inversion count of 'b' will bem1 = x3
After swap the values mentioned above will be
n2 = x3 + y3
andm2 = x2 + x3
respectively.After swap inversion count of all numbers > a, present in part2
(z2)
will increase by 1, coz 'a' which is less than them now will come after them. Similarly inversion count of all numbers > b, present in part2(z2+y2)
will decrease by 1, coz 'b' which is less than them now will come before them.so total change inversion count of whole permutation will be
n2+m2 - (n1+m1) + z2 - (z2+y2) = -2y2 - 1
, which is an odd number. So as change in inversion count is an odd number, after swapping two different numbers parity will definitely changeThank you very much man..i understood it. You are awesome
Swap of two adjacent elements will change parity, because it either increases of decreases number of inversions by 1.
Try to represent swap as odd number of adjacent swaps.
in the blog you have not made a relation between number of inversions and the cyclic representation of permutation..there must be some relation..You have proved the fact that permutation can be represented as composition of non-intersecting cycles..but how does it relate to the parity
Check comments above, I and bicsi have proved, that parity of permutation $$$p$$$ length $$$n$$$ is $$$n + cycles(p)$$$ and also parity of number of even cycles.
One thing to keep in mind is that, even though this algorithm is $$$O(n)$$$, it can be painfully slow for large values of $$$n$$$, for example, for $$$n=10^7$$$ it will usually take around $$$0.5$$$ seconds. I'm not aware of anything faster though maybe a Fenwick tree operating on single bits with XOR would be faster.
very good blog,,but some examples would have helped
Hello, I am having a bit of trouble seeing why a slightly easier approach was omitted (/ is wrong?)
With the above general idea in mind, can't we just represent our permutation as a number of transpositions and count the parity of this number?
example code:
my (AC) submission to 1591D using this idea.
*granted, the complexities (/ constants) of my solution and the one presented in the blog are virtually the same, but this seems more intuitive and I don't know why it wasn't presented.
Thank you! <3