题目链接
由题可知,随着固定的长度n的递减,ac的题目数sum是递增的,n的递减区间:
n1 n2 n3 n4…nm, 则有sum的递增区间sum1 sum2…sum m,题目需要求sum区间中的一段sumi sumi+1…sumj皆等于k,输出最小值ni,最大值nj. 当sum序列中不存在sumi=k则无最大值和最小值,输出-1.
结题方法:
显然的二分答案,由与n和sum都是有序序列,满足二分性质,直接两个二分一个求最小值,一个求最大值。即一个向ni二分,一个向nj二分。
代码如下
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define LL long long
#define MAXN 1000010
using namespace std;
int n,k,a[MAXN];
LL low=1,high=999999999999999;
int check(LL x,int lim){
LL len=0;
int sum=0;
for(int i=1;i<=n;i++){
len+=a[i];
if(len<0) len=0;
if(len>=x) len=0,sum++;
if(sum>lim) break;
}
return sum;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
LL ans=-1;
while(low<high){
LL mid=low+high>>1;
int t=check(mid,k);
if(t>k) low=mid+1;
if(t==k) ans=mid;
if(t<=k) high=mid;
}
printf("%lld ",ans);
if(ans==-1) return 0;
low=1,high=99999999999999,ans=-1;
while(low<high){
LL mid=low+high>>1;
int t=check(mid,k);
if(t==k) ans=mid;
if(t>=k) low=mid+1;
if(t<k) high=mid;
}
printf("%lld",ans);
return 0;
}