AtCoder Regular Contest 077 E
来源:互联网 发布:淘宝联盟高佣活动入口 编辑:程序博客网 时间:2024/06/05 00:51
题目链接: AtCoder Regular Contest 077 E - guruguru
题目大意
两个按钮, 一个可以使计数器+1(计数器数字从1-m), 当前值为m时, 再+1就变成了1
另一个按钮储存了一个值x, 按一下就从任意值会变成x
n-1次操作, 由一个数组a[n]描述, 第i次操作: 将计数器从a[i]调到a[i+1]
将x设置为某个值, 使得所有操作需要按按钮的次数总和最小, 输出这个最小值
范围:
思路
设置一个数组p, p[i] := 如果x在i位置, 对于所有操作, 使用第二个按钮能够减少的操作次数(相对于只使用第一个按钮)
设l = a[i], r = a[i+1]
, 如果l>r
, 令r = r+m
, 这样就不用考虑上界的问题了
那么对于每一对l, r, 如果r-l<=1
, 那么无论x在什么位置, 第二个按钮都不能减少操作次数
如果r-l>1
, 那么
x在l+2
位置使用第二个按钮能够减少1次操作, 在l+3
位置能减少2次… 在r位置能够减少r-(l+2)+1
次操作
所以p[l+2] += 1, p[l+3] += 2 ... p[r] += r-(l+2)+1
对每一对l, r如此处理, 得到最后的p数组
设all为只使用第一个按钮所需要的操作总次数
那么`最少操作次数 = all - max{p[i]+p[i+m]}, 1<=i<=m
以上就是基本思路, 如果不加其他优化, 直接写的话, 复杂度
能优化的地方是p[l+2] += 1, p[l+3] += 2 ... p[r] += r-(l+2)+1
这就是复杂度里m的来源, 可以将它优化到
如果要将p[l]到p[r]依次加上1, 2, … r-l+1
我们可以这样: p[i] += 1, p[r+1] -= r-l+1 + 1, p[r+2] += r-l+1
, 每次只更新这三个值, 最后再从头到尾p[i] += p[i-1]
具体的一组例子, 比如l=2, r=5
所以最后总复杂度
参考自: 来源
代码
#include <bits/stdc++.h>using namespace std;const int MAXN = 3E5 + 100;typedef long long ll;int n, m, a[MAXN];ll p[MAXN];int main(){ ll all = 0; scanf("%d%d", &n, &m); for(int i=0; i<n; ++i) scanf("%d", a+i); for(int i=1; i<n; ++i) { int l = a[i-1], r = a[i]; if(l>r) r += m; all += r-l; if(r-l>1) { p[l+2] += 1; p[r+1] -= (r-(l+2)+1) + 1; p[r+2] += (r-(l+2)+1); } } for(int i=1; i<=2*m; ++i) p[i] += p[i-1]; for(int i=1; i<=2*m; ++i) p[i] += p[i-1]; ll ans = -1; for(int i=1; i<=m; ++i) ans = max(ans, p[i]+p[i+m]); cout << all - ans << endl; return 0;}
- AtCoder Regular Contest 077 E
- AtCoder Regular Contest 077 E
- AtCoder Regular Contest 075 E
- AtCoder Regular Contest 079-E
- AtCoder Regular Contest 080 E
- AtCoder Regular Contest 080 E
- AtCoder regular contest 081 E
- AtCoder Regular Contest 077
- AtCoder Regular Contest 077
- 【树状数组】AtCoder Regular Contest 075 E
- 【Atcoder】Regular Contest 079 D E
- AtCoder Regular Contest 079 C D E
- AtCoder Regular Contest 082-E-ConvexScore
- AtCoder Regular Contest 077-C
- AtCoder Regular Contest 077-D
- Atcoder Regular Contest 072 E Alice in Linear Land
- AtCoder Regular Contest 078
- AtCoder Regular Contest 079
- 第四章 Lua模块开发
- CentOS7集成Mysql数据库安装和配置
- Android中的多进程通信
- c++中vector的=(赋值)操作是深复制
- ifelse的疑问
- AtCoder Regular Contest 077 E
- 第五章 常用Lua开发库1-redis、mysql、http客户端
- HDU 6029 Graph Theory(思路题)
- 图片缩放
- Animation Compression: Unity 5
- UE(虚幻)4 蓝图可视化编程进阶篇 03 鼠标拾取案例(接口)
- VM初始化错误,没有足够堆空间
- 如何让鼠标移入div不选中div中的文字,鼠标也改变样式
- 欢迎使用CSDN-markdown编辑器