Luogu P4343 自动刷题机

Luogu P4343 自动刷题机

注意到对于不同的 $n$,$k$ 显然满足单调性,二分答案即可。

注意 $k$ 随 $n$ 的增大而减小,以及二分时对 $\texttt{min}$ 和 $\texttt{max}$ 的不同处理方法。

#include<bits/stdc++.h>
#define N 100010
#define INF 0x7FFFFFFFFFFFffff

int l,k;
long long min,max;
int x[N];

namespace WalkerV {
	void Read() {
		scanf("%d%d",&l,&k);
		for(int i=1;i<=l;i++) {
			scanf("%d",&x[i]);
		}
		return;
	}

	long long Check(long long n) {
		long long ret=0,sum=0;;
		for(int i=1;i<=l;i++) {
			sum+=x[i];
			if(sum<0) {
				sum=0;
			}
			if(sum>=n) {
				ret++;
				sum=0;
			}
		}
		return ret;
	}

	long long LowerBoundMin(long long l,long long r) {
		long long ret=INF,mid;
		while(r-l>=2) {
			mid=(l+r)>>1;
			//printf("l:%d r:%d mid:%d\n",l,r,mid);
			if(Check(mid)<=k) {
				ret=mid;
				r=mid;
			}
			else {
				l=mid;
			}
		}
		return ret;
	}

	long long LowerBoundMax(long long l,long long r) {
		long long ret=0,mid;
		while(r-l>=2) {
			mid=(l+r)>>1;
			//printf("l:%d r:%d mid:%d\n",l,r,mid);
			if(Check(mid)<k) {
				ret=mid;
				r=mid;
			}
			else {
				l=mid;
			}
		}
		return ret;
	}
	void Solve() {
		min=LowerBoundMin(0,INF);
		max=LowerBoundMax(0,INF)-1;
		return;
	}

	void Print() {
		/*
		for(long long i=min-1;i<=max+1;i++) {
			printf("mid=%lld:%lld\n",i,Check(i));
		}
		*/
		if(min>max) {
			printf("-1\n");
		}
		else {
			printf("%lld %lld\n",min,max);
		}
		return;
	}
}

int main()
{
	WalkerV::Read();
	WalkerV::Solve();
	WalkerV::Print();
	return 0;
}
posted @ 2021-08-09 16:33  WalkerV  阅读(97)  评论(0编辑  收藏  举报