[CodeForces]460C Present
差分+二分
题意大概是对于一个序列,每次可以给某个长度为\(W\)的序列\(+1\),可以操作\(m\)次。问序列最小值的最大值是多少。
差分一下,每次二分到一个最小值的最大值就开始遍历整个数组,发现假如第\(i\)个数小于\(mid\),就令\(i->i+m-1\)上的值加到\(mid\)
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
const int N=100005;
int n,m,a[N],cf[N],ans,w;
bool ck(int x) {
int now=0,day=0;
for(int i=1;i<=n;i++) {
now+=cf[i];
if(now<x) day+=x-now,cf[i]+=x-now,cf[min(n+1,i+w)]-=x-now,now+=x-now;
if(day>m) return 0;
}
return 1;
}
signed main() {
scanf("%lld%lld%lld",&n,&m,&w);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),cf[i]=a[i]-a[i-1];
int l=0,r=1e18;
while(l<=r) {
int mid=l+r>>1;
if(ck(mid)) l=mid+1,ans=mid;
else r=mid-1;
for(int i=1;i<=n;i++) cf[i]=a[i]-a[i-1];
}
cout<<ans<<endl;
return 0;
}
我是咸鱼。转载博客请征得博主同意Orz