题目

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 \(\Sigma^{i=n}_{i=1}|p[i]-i|\).

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\ \ p_1, p_2, ... p_n,\)

\(k = 1: shift\ \ p_n, p_1, ... p_{n - 1},\)

\(...\)

\(k = n - 1: shift\ \ p_2, p_3, ... p_n, p_1.\)

输入格式

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

The second line contains n space-separated integers \(p_1, p_2, ..., p_n (1 ≤ p_i ≤ n)\) — the elements of the permutation. It is guaranteed that all elements are distinct.

输出格式

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.

样例

输入1

3
1 2 3

输出1

0 0

输入2

3
2 3 1

输出2

0 1

输入33

3
3 2 1

输出3

2 1

题解

如果纯模拟, 真的移动\(n\)次, 再加起来计算最小值, 复杂度太高, 需要一个\(O(n)\)的方法

很显然, 每次移动一位, 下标之间相差1, 可以看出规律来, 就是\(p[i]\)不变, 每次\(i\)增加\(1\), 超出范围的置为\(1\),

\(p[i] < i\)时, 随着移动, \(i\)逐渐变大, \(|p[i] - i|=i-p[i]\)逐渐变大, 当\(i\)超过\(n\)时, 重置为\(1\), 有可能变成第二种状态

\(p[i] > i\)时, 随着移动, \(i\)逐渐变大,\(|p[i] - i|=p[i] - i\)逐渐变小, 当移动到\(p[i] = i\)时, 转为第三种状态, 先记录下来\(p[i]\)与\(i\)最初的距离, 当移动次数与距离相等时, 转换状态

\(p[i] = i\)时, \(|p[i] - i|=0\), 再移动将会转为第一种状态.

最开始计算出所有数字之和, 根据移动次数, 处于三个状态的数字个数即可直接计算出现在的\(\Sigma^{i=n}_{i=1}|p[i]-i|\)

\(n\)次循环中, 取最小值输出

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
long long p[maxn], has[maxn << 1];
int main() {
long long n, bigger = 0, smaller = 0, equ = 0, ans1 = 0, ans2 = 0;
scanf("%lld", &n);
for (long long i = 1ll; i <= n; i++) {
scanf("%lld", &p[i]);
if (p[i] > i) bigger++, has[p[i] - i]++;
else if (p[i] == i) equ++, has[0]++;
else smaller++;
ans1 += abs(p[i] - i);
}
long long temp = ans1;
for (long long last = n - 1ll, delta = 1ll; last >= 1ll; last--, delta++) {
temp += equ + smaller - bigger;
smaller += equ;
bigger -= has[delta];
if (p[last + 1] >= last + 1ll) has[p[last + 1] - last - 1]--;
has[p[last + 1] - 1 + delta]++;
equ = has[delta];
if (p[last + 1] > 1ll) bigger++;
smaller = n - equ - bigger;
temp -= abs(p[last + 1] - n - 1ll) - abs(p[last + 1] - 1ll);
if (temp < ans1) ans1 = temp, ans2 = delta;
}
printf("%lld %lld\n", ans1, ans2);
return 0;
}

CF819B Mister B and PR Shifts 题解的更多相关文章

  1. [CF819B]Mister B and PR Shifts

    题意:定义一个排列$p_{1\cdots n}$的“偏移量”$D=\sum _{i=1}^n\left|p_i-i\right|$ 求它所有的轮换排列中偏移量最小的是多少,要求输出轮换序数 暴力就是求 ...

  2. CF819B Mister B and PR Shifts 思维题

    分析 这道题\(n\leq10^{6}\),显然\(n^{2}\)的暴力是无法解决问题的 那么我们可以考虑数列的某一种性质 因为最终的答案是\(\sum{n \atop i=1} |p_i - i|\ ...

  3. Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts

    Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts 题意:给一个长度为\(n\)的排列,每次可以向右循环移位一次,计算\(\sum_{i= ...

  4. Mister B and PR Shifts,题解

    题目链接 分析: 题意很明白,不再多说了,直接分析题目,首先想一想暴力,直接枚举起点,然后求出来,时间复杂度n*n,显然不太好,所以我们考虑换一种方法枚举,当然本质还是枚举,其实你会发现变化i次和i+ ...

  5. codeforces 820 D. Mister B and PR Shifts(思维)

    题目链接:http://codeforces.com/contest/820/problem/D 题意:求.有一种操作 k = 0: shift p1, p2, ... pn, k = 1: shif ...

  6. D. Mister B and PR Shifts

    ;//开两倍空间 int n; arr p,cnt; int l,r,m; ll sum = ,ans; int main() { // file("test"); sdf(n); ...

  7. Codeforces Round #421 (Div. 2)D - Mister B and PR Shifts(模拟)

    传送门 题意 给出n个数,计算在进行n-1次右移中\(min\sum_{i=1}^nabs(p_i-i)\) 分析 我们设置cnt[p[i]-i]为一个数p[i]与它标准位置(如1的标准位置为1)的左 ...

  8. codeforces 819B - Mister B and PR Shifts(思维)

    原题链接:http://codeforces.com/problemset/problem/819/B 题意:把一个数列整体往右移k位(大于n位置的数移动到数列前端,循环滚动),定义该数列的“偏差值” ...

  9. CF820D Mister B and PR Shifts

    题目链接:http://codeforces.com/problemset/problem/820/D 题目大意: 给出一个\(n\)元素数组\(p[]\),定义数组\(p[]\)的误差值为\(\su ...

随机推荐

  1. awardRotate转盘插件文字模糊问题和图片加载问题

    前言 最近在做一个转盘抽奖页面,使用了awardRotate.js发现字体和图片都有模糊,绘制的时候图片绘制不全,搜索一下之后发现针对awardRotate的解决方法比较少,针对canvas的比较多, ...

  2. @Transactional 事务的底层原理

    最近同事发现一个业务状态部分更新的bug,这个bug会导致两张表的数据一致性问题.花了些时间去查问题的原因,现在总结下里面遇到的知识点原理. 问题一:事务没生效 我们先看一段实例代码,来说明下问题: ...

  3. jmeter 性能测试入门手册分享

    深思熟虑之下,决定把这份性能测试入门手册分享给大家 最初整理这份教程的是因为自己在学习性能测试的过程中踩过了很多的坑,遇到了 数不清的问题,于是就想着将这些解决的问题全都归拢在一个文档里,方便自己查阅 ...

  4. CSS3如何实现div闪烁效果

    效果: Html: <h1 class="blink">花花世界</h1> Css: @keyframes fade { from { opacity: 1 ...

  5. <VCC笔记> Assumption

    接下来是第二种注释语句类型Assumption.语法_(Assume E), 这个表达式是让VCC在接下来的额推理中,无视表达式E, 直接认可表达式E. 例: int x, y; _(assume x ...

  6. 一文读懂 Java 异常体系

    写程序的时候,编辑器会提示错误,关键字拼错了,语法不符合规则,不符合泛型:程序编译的时候,编译器会提示错误,检查是否符合 Java 的语法规范,没有通过编译器检查的程序就无法编译,也就无法运行.这些都 ...

  7. Android学习笔记通过Toast显示消息提示框

    显示消息提示框的步骤 这个很简单我就直接上代码了: Button show = (Button)findViewById(R.id.show); show.setOnClickListener(new ...

  8. python测试标准库doctest

    引言: doctest是python的一个测试用标准库. 顾名思义,这个模块会寻找程序里面看起来像交互式Python会话的文本片段,然后运行这个会话,来判断实际运行结果和你希望的结果是否一致. 这个模 ...

  9. 客户端软件GUI开发技术漫谈:原生与跨平台解决方案分析

    原生开发应用开发 Microsoft阵营的 Winform WinForm是·Net开发平台中对Windows Form的一种称谓. 如果你想深入的美化UI,需要耗费很大的力气,对于目前主流的CSS样 ...

  10. 三文搞懂学会Docker容器技术(下)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...