【题解】
二分答案
在计算前缀和时减去mid,即s[i]=s[i-1]+a[i]-mid
这样只要有s[i]-s[j]>=0,且i-j>=m,那么mid就是符合条件的
用Min记录s[0]~s[i-m]中最小的s,即可做到O(n)判断
1 #include<cstdio> 2 #include<algorithm> 3 #define LL long long 4 using namespace std; 5 const int maxn=200010; 6 LL n,m,Max,l,r,mid,a[maxn],s[maxn]; 7 void read(LL &k){ 8 k=0; int f=1; char c=getchar(); 9 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 10 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 11 k*=f; 12 } 13 LL min(LL a,LL b){return a>b?b:a;} 14 bool check(LL x){ 15 LL Min=Max+1;//Min用来表示s[0]~s[i-m]中最小的s 16 for(int i=1;i<=n;i++){ 17 s[i]=s[i-1]+a[i]-x; 18 if(i>=m) Min=min(s[i-m],Min);//更新Min 19 if(s[i]-Min>=0) return 1; 20 } 21 return 0; 22 } 23 int main(){ 24 read(n); read(m); 25 for(int i=1;i<=n;i++) read(a[i]),a[i]*=1000,Max+=a[i],l=min(a[i],l),r=max(a[i]+1,r); 26 while(l+1<r)if(check(mid=(l+r)>>1)) l=mid; else r=mid; 27 return printf("%lld",l),0; 28 }