Codeforces987 E. Petr and Permutations(思维+逆序对)

题意:

一开始有一个长度为n的原排列a,
一次操作随机选择两个不同位置的数a(i)和a(j),然后交换。
Petr会进行3n次操作,Alex会进行7n+1次操作。

现在给出结果序列,要求判断结果序列是经过谁的操作得到的。

数据范围:1e3<=n<=1e6

解法:

因为是排列,每个数都不同,
所以每次交换一定会使得逆序对数量的奇偶性变化。

3n和7n+1的奇偶性一定不同,因此序列的逆序对数量奇偶性也一定不同。
那么直接计算出给定排列的奇偶性就能判断答案了。

code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxm=1e6+5;
int a[maxm];
int n;
struct BIT{
    int c[maxm];
    int lowbit(int i){
        return i&-i;
    }
    void add(int i,int t){
        while(i<maxm){
            c[i]+=t,i+=lowbit(i);
        }
    }
    int ask(int i){
        int ans=0;
        while(i){
            ans+=c[i],i-=lowbit(i);
        }
        return ans;
    }
}T;
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        T.add(a[i],1);
        ans+=i-T.ask(a[i]);
    }
    if(n%2==0&&ans%2==0){
        puts("Petr");
    }else if(n%2==1&&ans%2==1){
        puts("Petr");
    }else{
        puts("Um_nik");
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值