思路:
二分+贪心。注意LL的应用。
数据生成器:
#include<bits/stdc++.h>
using namespace std;
#define maxn 5
#define maxr 5
#define maxk 5
#define Rand() (rand()+rand()%19260817)
int n,r,k;
int main() {
srand(time(NULL));
n=Rand()%maxn+1;
r=Rand()%maxr+1;
k=Rand()%maxk;
printf("%d %d %d\n",n,r,k);
for(int i=1;i<=n;i++) printf("%d ",Rand()%maxk+1);
return 0;
}
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 500000
#define ll long long
#define inf ((1LL)<<60)
ll n,r,k;
ll a[maxn*3+5],c[maxn*3+5];
ll tg[maxn*3+5];
bool judge(ll x) {
memset(tg,0,sizeof(tg));
ll s=0,b=0;
for(int i=1;i<=n;i++) {
b+=a[i];
b-=tg[i];
if(b<x) {
ll y=x-b;
tg[i+2*r+1]+=y;
b+=y;
s+=y;
}
if(s>k) return 0;
}
return 1;
}
ll binsearch(){
ll l=0,r=inf;
while(l+1<r) {
ll mid=l+(r-l)/2;
if(judge(mid)) l=mid;
else r=mid;
}
if(judge(l+1)) return l+1;
if(!judge(l)) return l-1;
else return l;
}
int main(){
scanf("%lld%lld%lld",&n,&r,&k);
for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
for(int i=1;i<=n;i++) {
if(i>r) a[i-r]+=c[i];
else a[1]+=c[i];
a[i+r+1]-=c[i];
}
ll ans=binsearch();
if(ans<0) ans=0;
printf("%lld",ans);
return 0;
}