您的位置:首页 > 其它

Codeforces Round #421 (Div. 1):B. Mister B and PR Shifts 思维,乱搞

2017-07-02 14:14 363 查看
B. Mister B and PR Shifts

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Some time ago Mister B detected a strange signal from the space, which he started to study.

After some transformation the signal turned out to be a permutation p of length n or its cyclic shift. For the further investigation Mister B need some basis, that’s why he decided to choose cyclic shift of this permutation which has the minimum possible deviation.

Let’s define the deviation of a permutation p as .

Find a cyclic shift of permutation p with minimum possible deviation. If there are multiple solutions, print any of them.

Let’s denote id k (0 ≤ k < n) of a cyclic shift of permutation p as the number of right shifts needed to reach this shift, for example:

k = 0: shift p1, p2, ... pn,
k = 1: shift pn, p1, ... pn - 1,
...,
k = n - 1: shift p2, p3, ... pn, p1.


Input

First line contains single integer n (2 ≤ n ≤ 106) — the length of the permutation.

The second line contains n space-separated integers p1, p2, …, pn (1 ≤ pi ≤ n) — the elements of the permutation. It is guaranteed that all elements are distinct.

Output

Print two integers: the minimum deviation of cyclic shifts of permutation p and the id of such shift. If there are multiple solutions, print any of them.

Examples

input

3

1 2 3

output

0 0

input

3

2 3 1

output

0 1

input

3

3 2 1

output

2 1

解法:想了2天,蒟蒻还是没想到怎么做orz,只能求助网上的大神了。然后==会了一种乱搞的做法。

题意:有n个数,从1到n乱序排列,定义这n个数的秩序值为∑abs(a[i]-i) (1<=i<=n), 你每次将这个数组向右循环移位p次,问p等于多少时,这n个数的秩序值最小?

记录下每个数是在目标位置的左边还是右边,存下所有在目标左边的数,

cur[i]表示初始数组中有多少个数在它目标左边第i个位置上

->注意要存下一开始在目标左边(包括在目标上)的个数L,以及目标右边的数的个数r

之后直接模拟右移,对于第i次右移,L = L-cur[i-1], r = r+cur[i-1],即当次位移刚好有cur[i-1]个数原本在目标位置左边及目标上跑到了目标位置的右边,

每次的秩序值便是初始秩序值-L+r+特判最后一个数移到第一个数所产生的影响

但注意计算之后L还要+1,r还要-1因为最后一个数跑到了第一个

复杂度O(n)

思路来自:http://blog.csdn.net/jaihk662/article/details/73825315

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+7;
int n,cur[maxn*2],p[maxn],L,R,pos;
LL sum, ans;
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", &p[i]);
for(int i=1; i<=n; i++){
if(p[i]>=i){
L++;
cur[p[i]-i]++;
}
else{
R++;
}
sum += abs(i-p[i]);
}
ans = sum;
for(int k = 0; k < n; k++){
L -= cur[k];
R += cur[k];
sum = sum - L + R - abs(p[n-k]-(n+1)) + p[n-k] - 1;
cur[p[n-k]+k]++;
L++,R--;
if(sum < ans){
ans = sum, pos = k+1;
}
}
printf("%lld %d\n", ans, pos);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐