zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    OpenSSL证书生成
    支付宝支付流程
    前端获取用户位置信息
    微信公众号开发(三)
    微信公众号开发(二)
    微信公众号开发(一)
    前端优化
    页面自适应
    CSS样式(二)
    CSS样式(一)
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/11367947.html
Copyright © 2011-2022 走看看