[洛谷]P4343 [SHOI2015]自动刷题机 (#二分答案)

题目描述

曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。

自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果:

1.写了xx行代码

2.心情不好,删掉了之前写的yy行代码。(如果yy大于当前代码长度则相当于全部删除。)

对于一个 OJ,存在某个固定的长度n>0n>0,一旦自动刷题机在某秒结束时积累了大于等于nn行的代码,它就会自动提交并 AC 此题,然后新建一个文件(即弃置之前的所有代码)并开始写下一题。SHTSC 在某个 OJ 上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个 OJ 的nn究竟是多少。所幸他通过自己在 OJ 上的 Rank 知道了自动刷题机一共切了kk道题,希望你计算nn可能的最小值和最大值。

输入格式

第一行两个整数ll,kk,表示刷题机的日志一共有ll行,一共了切了kk题。

第二行ll个整数x_1,...,x_lx1​,...,xl​。x_i≥0xi​≥0表示写了x_ixi​行代码,x_i<0xi​<0代表删除了这道题的-x_i−xi​行代码。

输出格式

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

输入输出样例

输入 #1复制

4 2
2
5
-3
9

输出 #1复制

3 7

说明/提示

对于20%的数据,n≤10

对于40%的数据,n≤100

对于 60%的数据,n≤2000

对于 100%,n≤100000,-10^9≤x_i≤10^9−109≤xi​≤109


思路

二分答案。不写二分答案其实就是模拟,当然会TLE。

#include <stdio.h>
#include <iostream>
#define ll long long int
#define inf 2e18+7
using namespace std;
ll l,k,minx,maxn,s,a[200001];
inline ll check(ll x)
{
	register ll i,sum(0),line(0);
	for(i=1;i<=l;i++)
	{
		sum+=a[i];//累加代码行数 
		if(sum>=x)//如果累加行数超过了mid 
		{
			line++;//AC+1 
			sum=0;
		}
		sum=max(sum,(ll)0);//sum<0要为- 
	}
	return line;
}
inline ll binary_max(ll l,ll r)
{
	ll mid,ans(-1);
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid)>k)
		{
			l=mid+1;
		}
		else
		{
			r=mid-1;
		}
		if(check(mid)==k)//句神烦的二分边界,这样写就A了 
		{
			ans=mid;
		}
	}
	return ans;
}
inline ll binary_min(ll l,ll r)
{
	ll mid,ans(-1);
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid)>=k)
		{
			l=mid+1;
			if(check(mid)==k)
			{
				ans=mid;
			}
		}
		else
		{
			r=mid-1;
		}
	}
	return ans;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	register ll i,j;
	cin>>l>>k;
	for(i=1;i<=l;i++)
	{
		cin>>a[i];
	}
	maxn=binary_max(1,inf);
	minx=binary_min(1,inf);
	if(minx!=-1)
	{
		cout<<maxn<<' '<<minx<<endl;
	}
	else
	{
		cout<<-1<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值