• CF460C Present


    题目链接:https://www.luogu.org/problem/CF460C

    思路:

    考虑二分答案。

    对于这$n$个数,我们可以从左往右,若发现小于当前答案的数,把$[i,i+w]$之间的所有数都加到当前答案的数值,判断总次数与$m$的关系就行了。

    对于更新和查询的操作,不妨使用树状数组维护差分数组。

    代码:

    #include <bits/stdc++.h>
    const int MAXN = 100050;
    const int INF = 1e9 + 5;
    using namespace std;
    int n, m, w, Min = INF, l, r, ans, a[MAXN], b[MAXN];
    struct Tree_Array {
        int lowbit(int x) { return x & (-x); }
        void add(int pos, int val) {
            for(int i = pos; i <= n; i += lowbit(i))
                b[i] += val;
        }
        int ask(int pos) {
            int sum = 0;
            for(int i = pos; i >= 1; i -= lowbit(i))
                sum += b[i];
            return sum;
        }
    }Tree; 
    bool check(int x) {
        int cnt = 0, last = 0;
        memset(b, 0, sizeof(b));
        for(int i = 1; i <= n; i++) {
            Tree.add(i, a[i] - x - last);
            last = a[i] - x;
        }
        for(int i = 1; i <= n; i++) {
            int res = Tree.ask(i);
            if(res < 0) {
                cnt += -res;
                if(cnt > m)
                    return false;
                Tree.add(i, -res);
                Tree.add(i + w, res);
            }
        }
        return true;
    }
    int main() {
        cin >> n >> m >> w;
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
            Min = min(Min, a[i]);
        }
        l = Min, r = Min + m;
        while(l <= r) {
            int mid = (l + r) >> 1;
            if(check(mid)) {
                ans = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    合并区间
    判断字符串是否是IP
    Python -- 异常处理
    python -- 双下方法
    python -- 判断函数和方法
    python -- 面向对象:反射
    Python -- 面向对象:类的成员
    Python -- 面向对象:类的约束
    Python -- 面向对象的三大特性及深入了解super()
    Python -- mro算法
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/11367947.html
Copyright © 2020-2023  润新知