bzoj 2792 [Poi2012]Well 二分+dp+two_pointer
题目大意
给出n个正整数X1,X2,...Xn,可以进行不超过m次操作,每次操作选择一个非零的Xi,并将它减一。
最终要求存在某个k满足Xk=0,并且z=max{|Xi - Xi+1|}最小。
输出最小的z和此时最小的k。
第一行两个正整数n, m (1<=n<=1,000,000, 1<=m<=10^18)。第二行n个正整数X1,X2,...Xn (Xi<=10^9)。
分析
我们考虑简单点的问题
我们要最小化z,考虑二分
对于没有要求变成0的问题
我们会尽可能使每个数操作后最大
因为没有+1操作
两个数相差大于mid时
只能大的数减下去
b[i]表示每个数最大是多少
从左往右扫一次,\(b[i]=min(b[i],b[i-1]+mid)\)
从右往左扫一次,\(b[i]=min(b[i],b[i+1]+mid)\)
然后我们枚举将哪一个数变成0
设枚举到i
我们只用找到最大的L满足\(b[L]<=(i-L)*mid\)
找到最小的R满足\(b[R]<=(R-i)*mid\)
此时(L,R)中的数一定要修改
修改成等差数列
稍微想一想可以证明此时对区间外的数没有任何影响
右注意到随着i增加,L-R区间也单调右移
two-pointer一下
solution
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
typedef long long LL;
using namespace std;
const int M=1000007;
int n;
LL lim,ss=0;
int a[M];
int b[M];
LL s[M];
LL calc(LL d,LL l){
return d*(l*(l+1)/2);
}
int check(int del){
LL c1=0,c2=0;
int i;
for(i=1;i<=n;i++) b[i]=a[i];
for(i=2;i<=n;i++) b[i]=min(b[i],b[i-1]+del);
for(i=n-1;i>0;i--) b[i]=min(b[i],b[i+1]+del);
for(i=1;i<=n;i++){
c1+=a[i]-b[i];
s[i]=b[i]+s[i-1];
}
if(c1>lim) return 0;
int l=1,r=2;
for(i=1;i<=n;i++){
while(l<i&&b[l]<=(i-l)*del) l++;
while(r<=n&&b[r]>(r-i)*del) r++;
c2=s[r-1]-s[l-1];
c2-=calc(del,i-l);
c2-=calc(del,r-1-i);
if(c1+c2<=lim) return i;
}
return 0;
}
void solve(){
if(ss<=lim) {printf("1 0\n");return;}
int res=0,tp;
int l=1,r=1000000000,mid;
while(l<r){
mid=l+r>>1;
tp=check(mid);
if(tp){
r=mid;
res=tp;
}
else l=mid+1;
}
printf("%d %d\n",res,l);
}
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}
int main(){
int i;
scanf("%d%lld",&n,&lim);
for(i=1;i<=n;i++) a[i]=rd(),ss+=a[i];
solve();
return 0;
}
bzoj 2792 [Poi2012]Well 二分+dp+two_pointer的更多相关文章
- BZOJ 2792 Poi2012 Well 二分答案
题目大意:给定一个非负整数序列A.每次操作能够选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{Ai−Ai+1}最小,输出这个最小值以及此时最小的k 二分答案,然后验证的时候首 ...
- bzoj 2792: [Poi2012]Well【二分+贪心】
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const ...
- bzoj 2798 [Poi2012]Bidding 博弈论+dp
题目大意 A和B两个人在玩一个游戏,这个游戏是他们轮流操作一对整数(x,y). 初始时(x,y)=(1,0),可以进行三种操作: 将(x,y)变成(1,x+y). 将(x,y)变成(2x,y). 将( ...
- 二分+DP HDU 3433 A Task Process
HDU 3433 A Task Process Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- hdu 3433 A Task Process 二分+dp
A Task Process Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- BZOJ_2792_[Poi2012]Well_二分答案
BZOJ_2792_[Poi2012]Well_二分答案 Description 给出n个正整数X1,X2,...Xn,可以进行不超过m次操作,每次操作选择一个非零的Xi,并将它减一. 最终要求存在某 ...
- 2018.10.24 NOIP模拟 小 C 的数组(二分+dp)
传送门 考试自己yyyyyy的乱搞的没过大样例二分+dp二分+dp二分+dp过了606060把我自己都吓到了! 这么说来乱搞跟被卡常的正解比只少101010分? 那我考场不打其他暴力想正解血亏啊. 正 ...
- 【BZOJ】4985: 评分【DP】
4985: 评分 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 148 Solved: 75[Submit][Status][Discuss] Des ...
- 「学习笔记」wqs二分/dp凸优化
[学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...
随机推荐
- Java Marker Interface
先看看什么是标记接口?标记接口有时也叫标签接口(Tag interface),即接口不包含任何方法. 在Java里很容易找到标记接口的例子,比如JDK里的Serializable接口就是一个标记接口. ...
- TCP/UDP 协议介绍
TCP/IP五层网络结构模型 物理层:物理层建立在物理通信介质的基础上,作为系统和通信介质的接口,用来实现数据链路实体间透明的比特 (bit) 流传输.只有该层为真实物理通信,其它各层为虚拟通信 数据 ...
- webpack开始一个项目的步骤
这几天在学习Vue 用到了webpack打包工具 开始一个项目的时候 需要配置很多项 刚开始写的时候 配置文件总是缺什么再去配置什么 创建项目就用了半个小时 后来觉得应该有个步骤 这样 ...
- 转 救命的教程 anaconda下载安装包网络错误的解决办法
折腾了一天,终于找到了这个解决办法 https://blog.csdn.net/sinat_29315697/article/details/80516498
- MySQL 自学笔记_Union(组合查询)
1. Union查询简介 组合查询:有时在使用select语句进行数据查询时,想要将多个select语句在一个查询结果中输出,此时就需要使用Union关键字. Union的使用方法:用union将多个 ...
- 201621123080《Java程序设计》第三周学习总结
Week03-面向对象入门 1. 本周学习总结 2. 书面作业 1.以面向对象方式改造数据结构作业'有理数'(重点) 1.1 截图你主要代码(需要在程序中出现你的学号和姓名)并粘贴程序的git地址. ...
- Linux 常用命令(三)
一.less --分页查看文件:方面查阅(编辑)大文件 说明:支持方向键盘和鼠标向上向下浏览 -N 显示行号 二.head --output the first part of files 默认显示 ...
- Python学习笔记:输入输出,注释,运算符,变量,数字类型,序列,条件和循环控制,函数,迭代器与生成器,异常处理
输入输出 输入函数input()和raw_input() 在Python3.x中只有input()作为输入函数,会将输入内容自动转换str类型: 在Python2.x中有input()和raw_inp ...
- Python 基本数据类型 (二) - 字符串1
# ----------- 首字母大写 ---------- test = "alex is a man" v = test.capitalize() print(v): Alex ...
- 使用TensorFlow的卷积神经网络识别手写数字(3)-识别篇
from PIL import Image import numpy as np import tensorflow as tf import time bShowAccuracy = True # ...