http://codeforces.com/problemset/problem/954/G
二分答案
检验的时候,从前往后枚举,如果发现某个位置的防御力<二分的值,那么新加的位置肯定是越靠后越好
差分即可
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 500001 typedef long long LL; int n,r; LL k; LL sum[N]; LL cf[N]; template<typename T> void read(T &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); } } bool check(LL x) { LL rest=k,need; LL add=0; memset(cf,0,sizeof(cf)); for(int i=1;i<=n;++i) { add+=cf[i]; if(sum[i]+add<x) { need=x-sum[i]-add; rest-=need; if(rest<0) return false; cf[i+1]+=need; if(i+2*r<n) cf[i+2*r+1]-=need; } } return true; } int main() { read(n); read(r); read(k); int x; for(int i=1;i<=n;++i) { read(x); sum[max(0,i-r)]+=x; if(i+r<n) sum[i+r+1]-=x; } for(int i=1;i<=n;++i) sum[i]+=sum[i-1]; LL l=0,r=2e18,mid,ans=0; while(l<=r) { mid=l+r>>1; if(check(mid)) ans=mid,l=mid+1; else r=mid-1; } cout<<ans; }