zoukankan      html  css  js  c++  java
  • Codeforces 1373F

    Description

    思路

    如果我们知道某一个站(b_i)到对(a_i)的贡献是多少,那么就可以用贪心求解(因为这样我们就知道(b_i)(a_{i+1})的贡献,从而知道(b_{i+1})(a_{i+1})...)。所以可以考虑二分(b_i)(a_i)的贡献。

    可以把(b_i)(a_i)的贡献看作流水,这里(a_i)就是容量。

    确定了(b_i)(a_i)的贡献(设为c)后,有两种结果:

    1. 一种是断流(由于(b_i)(a_i)贡献太多,导致对(a_{i+1})贡献过少,导致后面断流);
    2. 一种是流一圈后由(b_{i-1})流回(a_i)(设流回的量为x)。对于后一种,(b_i)(a_i)的贡献每减少1,x至多增加1,因为流一圈过程中可能有地方满流了,继续增加流量,x也不会增加。

    所以二分找到使得流回量x>0的最大的c。这个就是边界情况,判断x+c是否大于等于(a_i)即可。
    这里取(a_i)(a_1)

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <stack>
    #include <deque>
    #include <cmath>
    #include <iomanip>
    #include <cctype>
     
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0);
    #define FILE freopen("..//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
    #define FI freopen("..//data_generator//in.txt","r",stdin)
    #define FO freopen("res.txt","w",stdout)
    #define pb push_back
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
     
    typedef long long ll;
    using namespace std;
    /*-----------------------------------------------------------------*/
     
    #define INF 0x3f3f3f3f
    const int N = 1e6 + 10;
    const double eps = 1e-8;
     
    int arr[N];
    int brr[N];
     
    int check(int x, int n) {
        int out = brr[1] - x;
        for(int i = 2; i <= n; i++) {
            int p = i > n ? i - n : i;
            int cap = arr[p];
            cap = max(cap - out, 0);
            if(cap > brr[p]) return -1;
            out = brr[p] - cap;
        } 
        return out;
    }
     
    int main() {
        IOS;
        int t;
        cin >> t;
        while(t--) {
            int n;
            cin >> n;
            for(int i = 1; i <= n; i++) cin >> arr[i];
            for(int i = 1; i <= n; i++) cin >> brr[i];
            int l = 0, r = brr[1];
            while(l <= r) {
                int mid = (l + r) / 2;
                if(check(mid, n) >= 0) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }   
            
            if(r < 0) cout << "NO" << endl; //一直断流
            else if(r + check(r, n) >= arr[1]) cout << "YES" << endl;
            else cout << "NO" << endl;
        }
    }
    
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/limil/p/13196715.html
Copyright © 2011-2022 走看看