CF460C Present

Posted beyondlimits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

以上是关于CF460C Present的主要内容,如果未能解决你的问题,请参考以下文章

HP ProLiant BL460c G7 事件WHEA-Logger&ID47

惠普HP ProLiant BL460c Gen8无法用U盘做启动盘

关于安排

CF 爆发者

[CF930E]/[CF944G]Coins Exhibition

CF怎么改名