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;
}