CF954G Castle Defense
题意读了半天,还是找的别人博客上的翻译
有n个点 ,每个点最开始有ai个弓箭手,
在第i个位置的弓箭手可以给[i-r,i+r]区间加上1的防御,你还有k个弓箭手,要求你最大化最小防御值
这个审完题面后,虽然很容易想到二分,但是我写不出check来(哭
正解是加上贪心的想法 ,在一个mid下我们从右向左扫的时候,我们区间的弓箭手是放在最右端最好的
#include<bits/stdc++.h> #define mid ((l+r)>>1) #define int long long using namespace std; const int N=5e6+7; const int inf=1e18+7; int n; int len,k; int a[N]; int sum[N]; int l=inf>>1,r=inf<<1; int w[N]; bool pd(int m) { int f=k; int x=0; memset(w,0,sizeof(w)); for(int i=1;i<=n;i++) { x+=w[i]; if(sum[min(i+len,n)]-sum[max(i-len-1,0ll)]+x<m) { int dif=m-sum[min(i+len,n)]+sum[max(0ll,i-len-1)]-x; if(dif>f) return 0; f-=dif; x+=dif; w[i+len*2+1]-=dif; } } return 1; } int ans; signed main() { ios::sync_with_stdio(false); cin>>n>>len>>k; for(int i=1;i<=n;i++) { cin>>a[i]; sum[i]=sum[i-1]+a[i]; l=min(l,a[i]); } while(l<r) { if(pd(mid)) { ans=mid; l=mid+1; } else r=mid; } cout<<ans; return 0; }