CodeForces-820D Mister B and PR Shifts
来源:互联网 发布:北京网络地板生产厂家 编辑:程序博客网 时间:2024/05/22 10:55
/* 这题十分值得多多回顾,常拿出来重做一次 这题真是想得极为艰难的一道题,不过想明白以后,发现其实还是挺有意思的(其实也不算是我想明白的,是请教了别人,再纠结了很久,不然以我的智商,别说自己想,看懂blog上的代码都相当艰难了...)... shift记录右移多少位可使 a[i] == i;确切说,下标为移动次数,值为移动下标次数时,满足 a[i] == i的个数 参考系一直是最初的数组,而不是改变后的数组 用l来记录当前满足 a[i] > i的个数,则r == n - l(r在程序中没有写出,一直用n - l 来表达),之所以不取得a[i] >= i,是因为单独拿出等于的那种情况分析,由于后移,i变大,则 i - a[i]变大,a[i] <= i的两种情况一样,都是对绝对值总和的贡献度+1,a[i] < i则是对绝对值总和的贡献度-1,故而等于号应该放在r的那边 每次输入,若a[i] > i,说明可通过右移最终实现相等,一方面累加l,一方面更新shift数组中的对应元素。此外,每次输入后,都要累加a[i]-i的绝对值... 下一个for循环开始移动,每次移动,由于l和r的对应数据,分别导致贡献度-1和+1,所以d要减去l,加上r,但其实,是加上r-1,因为每次移动,最后的数据会被移动到最前,这个数据的贡献度变化量,是要单独算的,但我们之前在统计时,把它加到了r里(因为下标n,所有元素在1~n之间,满足 i >= a[i],恰好属于r对应的范围),所以要减去1 而此时数列最后的元素移到最前,使得d变化 abs(x -1) - abs(x - n) 此外,更新l,移动i次时,会有shift[i]个元素通过移动,达到元素和下标的相等,因此l要减去这些 再对最后的元素x单独处理,如果它等于1,则它会算到r的阵营,否则,按照下标和数组元素的关系,它会算到l的阵营,使得l自增,这种情况下,对应的shift也要更新,x-1为元素与下标之差,为此次移动后,还需要的移动次数,再加上已经移动了的i次...并取模n,因为移动是有循环的,如果已经右移(n+i)次,也可直接当作右移i次 这里,其实我有怀疑过,可能因为上一步的shift更新,导致某些数组元素,它计算过两次shift,但这无伤大雅,因为,画图感受下,如果之前就是a[i] > i,两次算出的右移次数,也就(n+i)次和i次的区别...而取模后就没有区别了 但是这步也一定要留下,别忘了可是也有a[i] < i的,它们若想相等,就必须位置先移到尾端,再从最前的1开始,才有可能实现...这里单独处理x时对shift的更新,恰恰就是为了这种情况,原来不能通过右移实现a[i] == i的情况,现在通过右移到末端,再从最左开始,有可能实现了,它们的shift也终于可以更新了(只有通过右移可以实现时,才会更新shift,而对应的原来不满足的点,一旦移到最前端,就有机会满足了) */
#include <bits/stdc++.h>typedef long long LL;const int N = 1e6 + 10;int a[N], shift [N]; // shift记录右移多少位可使 a[i] == i;确切说,下标为移动次数,值为移动下标次数时,满足 a[i] == i的个数 using namespace std;// shift记录右移多少位可使 a[i] == i;确切说,下标为移动次数,值为移动下标次数时,满足 a[i] == i的个数 int main(){int n;while (cin >> n){memset( shift, 0, sizeof(shift) );LL d = 0;int l = 0; // l 用来记录a[i] > i的个数,r = n - lfor ( int i = 1; i <= n; i++ ){cin >> a[i];if (a[i] > i) l++, shift[ a[i] - i ]++;d += abs (a[i] - i);}LL mind = d;int mini = 0;for ( int i = 1; i < n; i++ ){int x = a[n - i + 1]; //第i次移动前,数组的最后一个元素 d += (n - l - 1) - l + abs(x - 1) - abs(x - n);l -= shift[i];if (x != 1){l++;shift[(x - 1 + i) % n]++; }if ( d < mind ){mind = d;mini = i;}}cout << mind << " " << mini << endl; }return 0;}
阅读全文
0 0
- CodeForces-820D Mister B and PR Shifts
- CodeForces 820D Mister B and PR Shifts(思维题)
- Codeforces 819 B. Mister B and PR Shifts
- Codeforces 819B. Mister B and PR Shifts
- Codeforces Round 421 Div.2 D. Mister B and PR Shifts 思维 乱搞
- Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts
- Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts
- #421 Div.2 D. Mister B and PR Shifts
- CF 820D Mister B and PR Shifts 差分(区间+k*(x-L)+b)
- Codeforces Round #421 (Div. 1):B. Mister B and PR Shifts(瞎搞)
- Codeforces Round #421 (Div. 1):B. Mister B and PR Shifts 思维,乱搞
- Codeforces Round #421 Mister B and PR Shifts(暴力瞎搞)
- codeforces819B Mister B and PR Shifts -- 线段树
- codeforces819bMister B and PR Shifts
- Codeforces 819 D. Mister B and Astronomers 数论
- Codeforces 820B Mister B and Angle in Polygon
- codeforces 820B Mister B and Angle in Polygon
- CodeForces 820B Mister B and Angle in Polygon
- 关于线段树的作用与其他数据结构的替代
- ImageView的scaleType属性
- MySql错误代码1045的解决方案
- 8.14-集体智慧编程-4-提供推荐--未完
- FastDFS分布式文件系统
- CodeForces-820D Mister B and PR Shifts
- 关于会议
- Python Study (05)装饰器
- Oracle SQL性能优化
- 如何将Unity中的脚本文件转为dll文件
- learn English for ten years but still can not learn! Suggest you:then don't study(1)
- SUSE Linux 下 MySQL集群配置
- kotlin gradle core web vertx IDEA 2.1 2.2
- iOS 中宏定义反斜杠( \ )的作用