分析
经典的字眼,要求最小值最大。考虑二分答案。如何判断合法性。对于二分出来的最小值。从左向右扫一次,在考虑 时,我们已经保证
是一个合法的区间了,所以只有向后加才有意义。所以遇到小于二分出来的数时,直接
这个区间
。用差分数组维护一下就好了,当操作次数大于
时是不合法答案,时间复杂度为
。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
#define LL int
LL read() {LL x;scanf("%d",&x);return x;}
LL A[N],C[N],n,m,w;
bool check(LL x) {
LL tot = 0;memset(C,0,sizeof(C));
for(int i = 1;i <= n;i++) {
C[i] = C[i] + C[i-1];
if(A[i] + C[i] < x) {
LL c = x-A[i]-C[i];
tot+=c;C[i]+=c;
if(i+w <= n) C[i+w]-=c;
if(tot > m) return false;
}
}
return tot <= m;
}
int main() {
n = read();m = read();w = read();
for(int i = 1;i <= n;i++) A[i] = read();
LL l = 1,r = (1<<30),ans = 0;
while(l <= r) {
LL mid = l + r >> 1;
if(check(mid)) l = mid + 1,ans = max(ans,mid);
else r = mid - 1;
}
printf("%d\n",ans);
return 0;
}
京公网安备 11010502036488号