CF986B Petr and Permutations

原题链接

DOWNLOAD AS PDF

题目大意

Petr要打乱排列。他首先有一个从\(1\)\(n\)的顺序排列,然后进行\(3n\)次操作,每次选两个数并交换它们。

Alex也要打乱排列。他与Petr唯一的不同是他进行\(7n+1\)次操作。

给定一个\(1\)\(n\)的排列。问是由谁打乱的。如果是Petr,输出"Petr",否则输出"Um_nik"(不是Alex)

(by \(\color{red}\sf{AKEE}\)

题解

都是\(O(n\log n)\)的?

我来一发\(O(n)\)的。

首先我们考虑怎么快速还原这个序列。

很显然的一个贪心策略就是假设序列为\(\{a_i\}\),不断把\(a_{a_i}\)\(a_i\)交换直到\(a_i=i\)

这样做我们发现交换次数是\(O(n)\)级别的。

然后我们发现要一个序列交换后形成交换前的序列交换次数只能是偶数。所以该交换次数与PetrAlex的奇偶性相同。

于是只要判一下奇偶即可。

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1000005;

int aa[maxn];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &aa[i]);
    int ans = 0;
    for(int i = 1; i <= n; ++i)
    {
        while(aa[i] != i)
        {
            swap(aa[aa[i]], aa[i]);
            ans++;
        }
    }
    if((n & 1) == (ans & 1)) // 判断奇偶性相同
        puts("Petr");
    else
        puts("Um_nik");
    return 0;
}
posted @ 2018-09-30 19:21  pfy_pfy  阅读(124)  评论(0编辑  收藏  举报