BZOJ_2792_[Poi2012]Well_二分答案

Description

给出n个正整数X1,X2,...Xn,可以进行不超过m次操作,每次操作选择一个非零的Xi,并将它减一。

最终要求存在某个k满足Xk=0,并且z=max{|Xi - Xi+1|}最小。
输出最小的z和此时最小的k。

Input

第一行两个正整数n, m (1<=n<=1,000,000, 1<=m<=10^18)。第二行n个正整数X1,X2,...Xn (Xi<=10^9)。

Output

输出k和z。数据保证方案一定存在。

Sample Input

16 15
8 7 6 5 5 5 5 5 6 6 7 8 9 7 5 5

Sample Output

1 2

HINT

将X序列变为

0 2 4 5 5 5 5 5 6 6 7 8 9 7 5 5
此时k=1,z=2,共操作了8+5+2=15次。
 

分析:首先肯定要二分答案出z,然后转化为判定是否能用小于等于m次操作使序列满足题意。
假设把第一个位置变成零,那么贪心的让后面比前面高度正好大z,扫一遍即可,可以发现最后的序列有若干个等差数列。
然后考虑怎么推出把其他位置i变成零对答案的贡献,i右边的数会下去一些,i左边的数会上去一些,可以发现这个满足单调性。
设f[i]为把第i个数变为0,左边需要改多少次,g[i]表示右边需要改多少次,双指针扫一遍,找到第一个大于|(j-i)|*z的位置,算出贡献即可。
有个小问题,可能序列一开始是不合法的,这是我们要从左往右再从右往左扫一遍,把不合法的部分削掉。
 
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000050
typedef long long ll;
int n,a[N],b[N],maxx;
ll m,s[N],f[N],g[N];
int check(int p) {
ll re=0;
int i,j;
for(i=1;i<=n;i++) b[i]=a[i];
for(int i=2;i<=n;i++)
if(b[i]-b[i-1]>p)
re+=b[i]-b[i-1]-p,b[i]=b[i-1]+p;
for(int i=n-1;i;i--)
if(b[i]-b[i+1]>p)
re+=b[i]-b[i+1]-p,b[i]=b[i+1]+p;
if(re>m) return 0;
for(i=1;i<=n;i++) s[i]=s[i-1]+b[i];
for(i=1,j=1;i<=n;i++) {
while(j<i&&b[j]<=1ll*(i-j)*p) j++;
f[i]=s[i-1]-s[j-1]-1ll*(i-j)*(i-j+1)/2*p;
}
for(i=n,j=n;i;i--) {
while(j>i&&b[j]<=1ll*(j-i)*p) j--;
g[i]=s[j]-s[i]-1ll*(j-i)*(j-i+1)/2*p;
}
for(i=1;i<=n;i++) if(f[i]+g[i]+b[i]+re<=m) return i;
return 0;
}
int main() {
scanf("%d%lld",&n,&m);
int i;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
maxx=max(maxx,a[i]);
}
int l=0,r=maxx+1;
while(l<r) {
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d %d\n",check(l),l);
}

BZOJ_2792_[Poi2012]Well_二分答案的更多相关文章

  1. BZOJ 2792 Poi2012 Well 二分答案

    题目大意:给定一个非负整数序列A.每次操作能够选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{Ai−Ai+1}最小,输出这个最小值以及此时最小的k 二分答案,然后验证的时候首 ...

  2. [POI2012]STU-Well(二分答案+神仙操作)

    给定一个非负整数序列A,每次操作可以选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{|Ai−Ai+1|}最小,输出这个最小lk以及最小值. Solution 最大值最小,显然 ...

  3. 【BZOJ2792】[Poi2012]Well 二分+双指针法

    [BZOJ2792][Poi2012]Well Description 给出n个正整数X1,X2,...Xn,可以进行不超过m次操作,每次操作选择一个非零的Xi,并将它减一. 最终要求存在某个k满足X ...

  4. CH Round #72树洞[二分答案 DFS&&BFS]

    树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...

  5. [CF752E]Santa Claus and Tangerines(二分答案,dp)

    题目链接:http://codeforces.com/contest/752/problem/E 题意:给n个橘子,每个橘子a(i)片,要分给k个人,问每个人最多分多少片.每个橘子每次对半分,偶数的话 ...

  6. [NOIP2011] 聪明的质检员(二分答案)

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...

  7. Codeforces Round #377 (Div. 2) D. Exams(二分答案)

    D. Exams Problem Description: Vasiliy has an exam period which will continue for n days. He has to p ...

  8. {POJ}{3897}{Maze Stretching}{二分答案+BFS}

    题意:给定迷宫,可以更改高度比,问如何使最短路等于输入数据. 思路:由于是单调的,可以用二分答案,然后BFS验证.这里用优先队列,每次压入也要进行检查(dis大小)防止数据过多,A*也可以.好久不写图 ...

  9. Leetcode 4 Median of Two Sorted Arrays 二分查找(二分答案+二分下标)

    貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的... 题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数. 二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第 ...

随机推荐

  1. Java---SSH(MVC)面试题

    1.        谈谈你mvc的理解 MVC是Model-View-Controler的简称.即模型-视图-控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开. MVC中的模型 ...

  2. 开启flume的远程调试功能

    各种组件,比如tomcat.storm.flume,我们都可以通过JMX方式开启远程调试,主要可以用来跟踪源码,了解程序内部的运行机制,其次,也有利于你修改源码. 首先,本质上是要修改flume本身启 ...

  3. 详解k8s组件Ingress边缘路由器并落地到微服务 - kubernetes

    写在前面 Ingress 英文翻译 进入;进入权;进食,更准确的讲就是入口,即外部流量进入k8s集群必经之口.这到大门到底有什么作用?我们如何使用Ingress?k8s又是如何进行服务发现的呢?先看一 ...

  4. [转]在Windows下编译ffmpeg完全手册

    本文的内容几乎全部来自于FFmpeg on Windows,但是由于国内的网络封锁,很难访问这个域名下的内容,因此我一方面按照我自己的理解和实践做了翻译,另一方面也是为了能提供一个方便的参考方法. 注 ...

  5. pydev 下Django 1.7 undefined variables from import问题的解决

    参考:http://stackoverflow.com/questions/24951029/pydev-django-undefined-variables-from-import 参考上面的帖子认 ...

  6. 在 Ubuntu 系统中部署 Git Server

    http://blog.csdn.NET/poisonchry/article/details/11849781 虽然有很多开源的Git仓库,不过并非所有都尽人意,譬如Github,Gitlab等,不 ...

  7. LruCache的使用及原理

    采用LRU算法实现的话就是将最老的数据删掉.利用LRU缓存,我们能够提高系统的性能.   一,是它本身已经实现了按照访问顺序的存储,也就是说,最近读取的会放在最前面,最不常读取的会放在最后(当然,它也 ...

  8. Codable实现json转Model,是时候干掉HandyJSON了!

    自从开始使用Swift做项目,一直都在使用HandyJSON,不可否认,HandyJSON在Swift4.0是个好东西,也尝试过其它json转mode的工具,最终发现还是HandyJSON最好用. 去 ...

  9. Java并发-容器

    同步容器类:同步容器类包括Vector和Hashtable.这些类实现线程安全的方式是:将它们的状态封装起来,并对每个公有方法进行同步,使得每次只有一个线程可以访问容器的状态.JDK1.2之后,提供了 ...

  10. IAAS-libvirt介绍。

    Libvirt介绍 Libvirt与hypervisor无关,其提供与多种操作系统虚拟化能力进行交互的API与工具库. Libvirt提供了一个通用稳定的抽象层,可以安全的操作物理机上的虚拟机,同时为 ...