Блог пользователя thematdev

Автор thematdev, 3 года назад, перевод, По-русски

Этот блог основан на задаче 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$$$ шагов. Далее возможны две ситуации

  1. Последние два элемента на месте, значит мы нашли искомое разбиение, и наша перестановка была чётной.

  2. Последние два элемента не на месте, то есть они поменяны местами. Значит текущая перестановка отличается от нашей одной транспозицией, но текущая перестановка чётная, значит наша нечётная.

Ниже приведена реализация

Реализация

Тем самым мы доказали теорему, и нашли простой алгоритм, позволяющий за $$$O(n)$$$ вычислить четность перестановки.

  • Проголосовать: нравится
  • +85
  • Проголосовать: не нравится

»
3 года назад, # |
  Проголосовать: нравится +50 Проголосовать: не нравится

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.

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +32 Проголосовать: не нравится

    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.

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      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)$$$

»
3 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

Are there any other problems similar to the one discussed above?

»
3 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

hey man very intersting blog...are there any other resources where i can further read about thus stuff??

»
3 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

I am not able to prove the lemma..any hints ??? thematdev

  • »
    »
    3 года назад, # ^ |
    Rev. 4   Проголосовать: нравится +3 Проголосовать: не нравится

    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).

    Lets define some terms

    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 be m1 = x3

    After swap the values mentioned above will be n2 = x3 + y3 and m2 = 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 change

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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.

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

very good blog,,but some examples would have helped

»
22 месяца назад, # |
  Проголосовать: нравится +38 Проголосовать: не нравится

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:

int transpCount = 0;
for (int i = 1; i < n; i++)
  if(invp[i] != i) {
    transposition(i, invp[i]);
    transpCount++;
  }
if (transpCount % 2 == 0)
  ; // even permutation
else
  ; // odd permutation

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