CF460C Present
二分答案
差分序列,前缀和一下就是原数组,然后如果这个数小于mid,那就让 这个位置后连续w个都+1(注意边界是n+1),显然加上不会影响答案
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
inline int read() {
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
int n,m,mm,w,a[N];
int dif[N],c[N];
bool check(int mid) {
int sum=0;
for(int i=1;i<=n;i++) {
sum+=c[i];
if(sum<mid) {
if(mm<mid-sum) return 0;
mm-=mid-sum;
c[min(i+w,n+1)]-=mid-sum;
sum+=mid-sum;
}
}
return 1;
}
int main() {
n=read();m=read();w=read();
int mx=0;
for(int i=1;i<=n;i++) a[i]=read(),mx=max(mx,a[i]);
for(int i=1;i<=n;i++) dif[i]=a[i]-a[i-1];
int l=1,r=mx+m;
int ans=0;
while(l<=r) {
int mid=(l+r)>>1;
memcpy(c,dif,sizeof(c));
mm=m;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}