正题
题目链接:https://www.luogu.org/problem/P4343
题目大意
nnn个操作每个操作加几行代码或减几行代码,若代码积累到xxx行就自动删除所有代码并切掉一道题。
已知道切掉了kkk题,求最大和最小的xxx
解题思路
因为xxx和切题的数量单调,所以可以二分答案即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=100010;
ll n,k,a[N],sum,maxs,l,r;
bool check(ll x)
{ll now=0,z=0; for(ll i=1;i<=n;i++){now+=a[i];now=max(now,0ll);if(now>=x) z++,now=0;}return (z>=k);
}
bool check2(ll x)
{ll now=0,z=0; for(ll i=1;i<=n;i++){now+=a[i];now=max(now,0ll);if(now>=x) z++,now=0;}return (z<=k);
}
bool checks(ll x)
{ll now=0,z=0; for(ll i=1;i<=n;i++){now+=a[i];now=max(now,0ll);if(now>=x) z++,now=0;}return (z==k);
}
int main()
{scanf("%lld%lld",&n,&k);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i],maxs=max(maxs,sum);l=1;r=(1e9)*n;while(l<=r){ll mid=(l+r)/2;if(check2(mid)) r=mid-1;else l=mid+1;}if(checks(l))printf("%lld ",l);else {printf("-1");return 0;}l=1;r=(1e9)*n;while(l<=r){ll mid=(l+r)/2;if(check(mid)) l=mid+1;else r=mid-1;}if(checks(r))printf("%lld",r);else printf("-1");
}