codeforces 1373F Network Coverage

题意

给一个\(n\)个点的环,每个点是一个容量为\(a[i]\)的空水池,给\(n\)个水桶,第\(i\)个桶里有\(b[i]\)升水,第\(i\)个桶只能给第\(i\)和第\(i+1\)个水池加水,特殊的,第\(n\)个桶只能给第\(n\)个和第\(1\)个水池加水,问是否能将所有水池加满。

分析

二分\(b[1]\)\(a[1]\)加了多少水,我们可以贪心的得到\(b[1]\)\(a[2]\)加了多少水,\(b[2]\)\(a[2]\)加了多少水....

有两种情况:

  • 断流,因为\(b[1]\)\(a[1]\)加了太多的水,导致无法加满\(a[2],a[3],\dots,a[n]\),要减少\(b[1]\)\(a[1]\)的供水量。
  • 能加满\(a[2],a[3],\dots,a[n]\),考虑增加\(b[1]\)\(a[1]\)的供水量,因为如果仍能加满\([2,n]\)的水池,在贪心过程中因为水池容量限制造成的损耗会减少,则\(b[1]\)\(b[n]\)\(a[1]\)的总供水量会增加。

Code

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
#define sz(a) int(a.size())
#define rson mid+1,r,p<<1|1
#define pii pair
#define lson l,mid,p<<1
#define ll long long
#define pb push_back
#define mp make_pair
#define se second
#define fi first
using namespace std;
const double eps=1e-8;
const int mod=1e9+7;
const int N=1e6+10;
const int inf=1e9;
int t,n,a[N],b[N];
int gao(int x){
	int res=b[1]-x;
	rep(i,2,n){
		res=b[i]-max(a[i]-res,0);
		if(res<0) return -1;
	}
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	//freopen("in","r",stdin);
	cin>>t;
	while(t--){
		cin>>n;
		rep(i,1,n) cin>>a[i];
		rep(i,1,n) cin>>b[i];
		int l=0,r=b[1],ans=0;
		while(l<=r){
			int mid=l+r>>1;
			int ret=gao(mid);
			if(ret==-1){
				r=mid-1;
			}else l=mid+1;
			if(ret!=-1&&ret+mid>=a[1]){
				ans=1;
			}
		}
		if(ans) puts("YES");
		else puts("NO");
	}
	return 0;
}

你可能感兴趣的:(codeforces 1373F Network Coverage)