BZOJ4590[Shoi2015]自动刷题机 二分

Posted CQzhangyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ4590[Shoi2015]自动刷题机 二分相关的知识,希望对你有一定的参考价值。

【BZOJ4590】[Shoi2015]自动刷题机

Description

曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置。自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模块会有两种可能的结果:
A.写了x行代码。
B.心情不好,删掉了之前写的y行代码。(如果y大于当前代码长度则相当于全部删除。)
对于每个OJ所有题目,存在某个固定的长度n>0。一旦自动刷题机在某秒结束时积累了大于等于n行的代码,它就会自动提交并AC此题,然后新建一个文件开始写下一题。SHTSC在某个OJ上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个OJ的n究竟是多少。所幸他通过自己在OJ上的Rank知道了机一共切了k道题。希望你计算n可能的最小值和最大值。

Input

第一行两个整数l,k,表示刷题机的日志一共有l行,一共了切了k题。
第二行l个整数,x1…xl。xi>=0表示写了xi行代码。xi<0表示删除了这道题的-xi行代码。
1<=l,k<=100000,|xi|<=10^9

Output

输出两个数a,b。分别代表n可能的最小值和最大值。如果不存在这样的n则输出-1。

Sample Input

4 2
2
5
-3
9

Sample Output

3 7
//样例1:如果n=2那么刷题机就会切掉3题。但如果n>7刷题机最多只能切1题。考虑n=4发生了什么。
第一秒:刷题机写了2行。
第二秒:刷题机又写了5行,共有7行,提交,自信AC。
第三秒:刷题机删掉了3行,共有0行。
第四秒:刷题机写了9行,共有9行,提交,自信AC。
一共AC了两题。

题解:显然满足单调性,直接二分。

判-1的时候要注意,最后最好是再check一下判断切题数是否正好等于K。并且二分的上界最好设的足够大。

 

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
ll n,m;
ll a1,a2;
ll v[100010];
ll check(ll x)
{
	ll i,ret=0;
	ll sum=0;
	for(i=1;i<=n;i++)
	{
		sum=max(0ll,sum+v[i]);
		if(sum>=x)	ret++,sum=0;
	}
	return ret;
}
inline ll rd()
{
	ll ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)	f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd(),m=rd();
	ll i;
	ll sum=0;
	for(i=1;i<=n;i++)	v[i]=rd(),sum+=(v[i]>0)?v[i]:-v[i];
	ll l=1,r=1ll<<60,mid;
	while(l<r)
	{
		mid=(l+r)>>1;
		if(check(mid)<=m)	r=mid;
		else	l=mid+1;
	}
	a1=r;
	l=2,r=1ll<<60;
	while(l<r)
	{
		mid=(l+r)>>1;
		if(check(mid)>=m)	l=mid+1;
		else	r=mid;
	}
	a2=l-1;
	if(check(a1)!=m||check(a2)!=m)	printf("-1");
	else	printf("%lld %lld",a1,a2);
	return 0;
}

 

以上是关于BZOJ4590[Shoi2015]自动刷题机 二分的主要内容,如果未能解决你的问题,请参考以下文章

COGS2642 / Bzoj4590 [Shoi2015]自动刷题机

BZOJ4590 [Shoi2015]自动刷题机

BZOJ4590: [Shoi2015]自动刷题机

BZOJ4590: [Shoi2015]自动刷题机

bzoj4590[Shoi2015]自动刷题机 二分

BZOJ4590 自动刷题机