ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF986B Petr and Permutations(逆序对)

2021-08-01 21:01:20  阅读:228  来源: 互联网

标签:random Alex nn CF986B Permutations 序数 Petr 逆序 permutation


题目描述

Petr likes to come up with problems about randomly generated data. This time problem is about random permutation. He decided to generate a random permutation this way: he takes identity permutation of numbers from 11 to nn and then 3n3n times takes a random pair of different elements and swaps them. Alex envies Petr and tries to imitate him in all kind of things. Alex has also come up with a problem about random permutation. He generates a random permutation just like Petr but swaps elements 7n+17n+1 times instead of 3n3n times. Because it is more random, OK?!

You somehow get a test from one of these problems and now you want to know from which one.

输入格式

In the first line of input there is one integer nn ( 103≤n≤106103≤n≤106 ).

In the second line there are nn distinct integers between 11 and nn — the permutation of size nn from the test.

It is guaranteed that all tests except for sample are generated this way: First we choose nn — the size of the permutation. Then we randomly choose a method to generate a permutation — the one of Petr or the one of Alex. Then we generate a permutation using chosen method.

输出格式

If the test is generated via Petr's method print "Petr" (without quotes). If the test is generated via Alex's method print "Um_nik" (without quotes).

题意翻译

Petr要打乱排列。他首先有一个从 11 到 nn 的顺序排列,然后进行 3n3n 次操作,每次选两个数并交换它们。

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

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

感谢@AKEE 提供翻译

输入输出样例

输入 #1复制

5
2 4 5 1 3

输出 #1复制

Petr

有引理:交换一个排列的两个数,序列的逆序对的奇偶性必然发生变化。

证明可以大致yy一下:当交换的两个数x,y距离小于等于1的时候易证,当大于1的时候将两个数之间的这些数分为三部分(设较大的数为y):大于y的,小于x的以及大于x且小于y的,分别分析逆序数的变化情况即可(注意夹起来的这部分元素自己的逆序数是不变的)。因为一开始整个排列是有序的,逆序数为0,所以若最终的逆序数为奇数说明交换了奇数次,否则交换了偶数次。因此判断一下3n的奇偶性和逆序数相同还是7n+1的奇偶性和逆序数相同即可。洛谷题解区有On做法更牛逼Orz

#include <bits/stdc++.h>
#define N 1000005
using namespace std;
int n, a[1000005], b[1000005];
void add(int x, int y) {
	for(; x <= N; x += (x & -x)) b[x] += y;
}
int ask(int x) {
	int ans = 0;
	for(; x; x -= x & -x) {
		ans += b[x];
	}
	return ans;
}
int main() {
	cin >> n;
	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
		cnt += ask(n) - ask(a[i]);//因为是排列 不会有相同的数
		add(a[i], 1);
	}
	//逆序对数一开始是0,交换3n次后应该为偶数,交换7n+1次后应该为奇数
	if((cnt & 1) == ((3 * n) & 1)) puts("Petr");
	else puts("Um_nik");
	return 0;
}

标签:random,Alex,nn,CF986B,Permutations,序数,Petr,逆序,permutation
来源: https://www.cnblogs.com/lipoicyclic/p/15087637.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有