【二分答案】P4343 [SHOI2015]自动刷题机

记录一道二分答案水题。。。


二分答案的一道板子题吧。关键在于while(l<=r),然后用一个ans来专门记录答案,L=mid+1,R=mid-1,最后想要找到答案最大值或者答案最小值,就在ans>=k l=N+1或者ans<=k r=N-1中来记录答案从而来得到二分答案的结果。

点击查看代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<bitset>
#include<queue>
#include<vector>
#include<cstdio>
#include<set>
#include<map>
#include<cmath>
#define ll long long
using namespace std;
const ll maxn = 1e5+5;
ll L,K;
ll X[maxn];
ll N;
ll isok() {
	ll ti = 0;
	ll now = 0;
	for(int i=1;i<=L;i++) {
		now += X[i];
		now = max(0ll,now);
		if(now>=N) {
			now = 0;
			ti++;
		}
	}
	return ti;
}
int main(){
	scanf("%lld%lld",&L,&K);
	ll yo = 0; bool fl = 0;
	for(int i=1;i<=L;i++) {
		scanf("%lld",&X[i]);
		if(X[i]>0) fl = 1;
	}
	ll l=1,r=1e18;
	ll ans1=-1,ans2=-1;
	while(l<=r) {
		N = (l+r)>>1;
		ll ans = isok();
		if(ans<=K) {
			r = N-1;
			if(ans==K) ans1=N;
		} else l = N+1;
	}
	l = 1 , r = 1e18;
	while(l<=r) {
		N = (l+r)>>1;
		ll ans = isok();
		if(ans>=K) {
			l = N+1;
			if(ans==K) ans2=N;
		} else r = N-1;
	}
	if(ans1==-1) puts("-1");
	else printf("%lld %lld\n",ans1,ans2);
	return 0;
}
posted @ 2021-09-14 23:03  Newuser233  阅读(33)  评论(0编辑  收藏  举报