CF819B Mister B and PR Shifts
Description
题目链接:CF819B
给定一个长度为 $n$ 的全排列 ${p_i}$,定义其偏移值为 $\sum_{i=1}^{n}p_i-i$,你可以将 $k\in[0,n-1]$ 个数从后面移到前面,使全排列的偏移值最小,输出最小偏移值和此时的 $k$,如果有多个符合输出任意一个。
$1\leq n \leq 10^6$
Solution
CF评分1900的黑题???肯定要来水一下呀(((
先观察下移动一次后偏移值的改变:中间一段的 $i$ 全部加一,最后一个数移到最前面。
移动两次后偏移值的改变:在移动一次后的序列中,中间一段的 $i$ 全部加一,最后一个数移到第二个数。
那么由此可以推理出移动 $j$ 次后偏移值的改变:在移动 $j-1$ 次后的序列中,所有 $i\in[1,n-1]$ 的数字的 $i$ 全部加一,最后一个数移动到 $j$。
考虑区间内数字所有 $i$ 加一的操作如何实现。
可以直接大力分类讨论:
- $p_i >i $,此时只需要记下此种类的个数以及 $p_i-i$ 的和,每次修改的时候只需要把和减去个数即可。
- $p_i\leq i$,此时也只需要记下此种类的个数以及 $i-p_i$ 的和,每次修改的时候只需要把和减去个数即可。
由于第一个种的数减多次后可能会变成第二种,所以需要为第一种的所有 $p_i-i$ 开个桶计数,注意维护下即可。
最后一个数移动到 $j$ 可以先考虑不管,那么所有数字都进行一次修改操作,然后把第 $(n+1)$ 个数移到第 $j$ 个即可,注意维护下上文种分类讨论中维护的所有东西。
思路写起来有点麻烦,但代码还是很简洁的。
Code
1 |
|