【Codeforces 1373F】Network Coverage 二分

题目链接:https://codeforces.ml/contest/1373/problem/F

题目大意:

给出两段序列a_i,b_i,a_i代表第i个点的商品需求量,b_i代表第i个点的供应量

b_i可以为a_i与a_(i+1)供应商品

问是否有一种分配方案使得a_i都满足需求?

题目思路:

首先确定,如果存在一种方案的话,b_i一定会向a_i+1提供了一定数目,但是数目不确定

所以可以想到去二分当前的数目,来判断提供的数目是否合法

此时从任意的bi开始是都可以的,为了简便从b_1开始

所以有以下三种情况:

如果中途出现,b[i] 全部给自己 也不能满足a[i],那么说明a[1]给少了

如果最后发现,d[1]剩余的不够了,那么说明给多了

否则,即为合法情况

所以,该函数满足单调性,进行二分即可

看到有O(n)的做法,但是没有理解,如果有大佬在评论下分享再好不过了

Code:

/*** keep hungry and calm CoolGuang!***/
#include 
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include
#include
#include
#include
#include
#define debug(x) cout<<#x<<":"<'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
int s = 0;
ll num[maxn],dp[maxn];
ll a[maxn],b[maxn],c[maxn],d[maxn];
int check(ll x){
    for(int i=1;i<=n;i++) d[i] = b[i],c[i] = 0;
    d[1] -= x;
    c[2] += x;
    for(int i=2;i<=n;i++){
        int diff = a[i] - c[i];
        int aim = i+1>n?1:i+1;
        if(diff < 0) c[aim] += d[i];
        else{
            if(d[i]>=diff){
                c[aim] += d[i]-diff;
                c[i] = a[i];
            }
            else return 1;///分配少了
        }
       // debug(c[i]);
    }
   // for(int i=1;i<=n;i++) printf("%lld ",c[i]);
    //printf("\n");
    if(c[1]+d[1]

 

你可能感兴趣的:(二分,尺取,思维锻炼)