zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 40 G. Castle Defense (二分+滑动数组+greedy)

    G. Castle Defense

    time limit per test

    1.5 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    Today you are going to lead a group of elven archers to defend the castle that is attacked by an army of angry orcs. Three sides of the castle are protected by impassable mountains and the remaining side is occupied by a long wall that is split into n sections. At this moment there are exactly a**i archers located at the i-th section of this wall. You know that archer who stands at section i can shoot orcs that attack section located at distance not exceeding r, that is all such sections j that |i - j| ≤ r. In particular, r = 0 means that archers are only capable of shooting at orcs who attack section i.

    Denote as defense level of section i the total number of archers who can shoot at the orcs attacking this section. Reliability of the defense plan is the minimum value of defense level of individual wall section.

    There is a little time left till the attack so you can't redistribute archers that are already located at the wall. However, there is a reserve of k archers that you can distribute among wall sections in arbitrary way. You would like to achieve maximum possible reliability of the defence plan.

    Input

    The first line of the input contains three integers n, r and k (1 ≤ n ≤ 500 000, 0 ≤ r ≤ n, 0 ≤ k ≤ 1018) — the number of sections of the wall, the maximum distance to other section archers can still shoot and the number of archers yet to be distributed along the wall. The second line contains n integers a1, a2, ..., a**n (0 ≤ a**i ≤ 109) — the current number of archers at each section.

    Output

    Print one integer — the maximum possible value of defense plan reliability, i.e. the maximum possible value of minimum defense level if we distribute k additional archers optimally.

    Examples

    input

    Copy

    5 0 65 4 3 4 9
    

    output

    Copy

    5
    

    input

    Copy

    4 2 01 2 3 4
    

    output

    Copy

    6
    

    input

    Copy

    5 1 12 1 2 1 2
    

    output

    Copy

    3
    

    https://codeforces.com/contest/954/problem/G

    题意:

    给你n个位置,每一个位置现在有a[i]个士兵驻守,,a[i]的士兵可以守护([i-r,i+r]),r是给定的数值。

    现在可以添加k个士兵,问你在最优分配的情况下,每一个位置(i)最小有多少个士兵守护?

    思路:

    最优分配情况的最小值,显然是可以二分答案。

    那么我们可以怎么check呢?

    假设当前二分到了mid

    我们对于每一个位置(i)可以获得当前num个士兵守护,如果num>=mid,继续i+1位置,

    如果num<mid,即需要用一些补充的士兵来增加该位置的驻守。

    最优分配策略是贪心的在(a[i+r])位置加(mid-num)个士兵。

    这样就涉及到了动态操作问题:

    单点修改,区间查询。

    如果用树状数组或者线段树来解决,会TLE(亲测),因为会多个log。

    那么我们可以用一个双指针进行滑动数组的方式来解决该问题。

    这样check的部分时间复杂度就是(O(n))

    外部的二分部分时间复杂度是(O(log_2R))

    R是二分的边界范围,通过数据范围分析可以知道R上限是2e18;

    那么整体的时间复杂度(O(n*log_2R))

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    
    inline void getInt(int* p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    ll k;
    int w;
    int n;
    ll a[maxn];
    ll tree[maxn];
    int lowbit(int x)
    {
        return -x & (x);
    }
    void add(int x, ll val)
    {
        while (x <= n)
        {
            tree[x] += val;
            x += lowbit(x);
        }
    }
    ll ask(int x)
    {
        ll res = 0ll;
        while (x)
        {
            res += tree[x];
            x -= lowbit(x);
        }
        return res;
    }
    typedef pair<int, ll> pil;
    std::vector<pil> v;
    bool check(ll mid)
    {
        ll temp = k;
        bool res = 1;
        ll num = 0ll;
        int l = 1;
        int r = 0;
        repd(i, 1, n)
        {
            while (r - i < w)
            {
                num += a[++r];
            }
            while (i - l > w)
            {
                num -= a[l++];
            }
            if (num < mid)
            {
                if (temp >= mid - num)
                {
                    temp -= mid - num;
                } else
                {
                    res = 0;
                    break;
                }
                a[min(i + w, n)] += mid - num;
                v.push_back(mp(min(i + w, n), mid - num));
                num = mid;
            }
        }
        for (auto &t : v)
        {
            a[t.fi] += -1ll * t.se;
        }
        v.clear();
        return res;
    
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        gbtb;
        cin >> n >> w >> k;
        repd(i, 1, n)
        {
            cin >> a[i];
            // add(i, a[i]);
        }
        ll l = 0ll;
        ll r = 2e18;
        ll mid;
        ll ans;
        while (l <= r)
        {
            mid = (l + r) >> 1;
            if (check(mid))
            {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    获取iphone当前的语言设置
    UIscrollView通过Button来实现view的切换的方法
    Citrix 客户端登录出现wfshell.exe 应用程序错误的解决方法
    WCF 学习资源
    There is no Citrix MetaFrame server configured on the specified address错误的解决方法
    ASP.NET AJAX,WCF,ADO.NET Entity 开发实例
    SC命令配置服务
    Citrix 客户端登录出现wfshell.exe 应用程序错误的解决方法
    删除子窗体中的控件中的某些属性时出现"Selection contains a component introduced in an ancestor form which cannot be deleted."错误的解决方法
    There is no Citrix MetaFrame server configured on the specified address错误的解决方法
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11705233.html
Copyright © 2011-2022 走看看