Codeforces 460C Present 二分答案

来源:互联网 发布:主机屋dedecms数据库 编辑:程序博客网 时间:2024/06/16 11:45

题目链接:http://codeforces.com/contest/460/problem/C

题意: 

给定一个n长的序列

每次可以给w长的区间内的数增加1

最多可以增加m次

使得 最后结果中最小的数 最大

问这个最小的数是多少

二分答案判可行。

#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <iostream>using namespace std;#define inf 1000000000#define N 100005int a[N];int b[N], add[N];bool ok(int x, int n, int m, int w){    for(int i = 1; i<= n; i++)b[i] = a[i];    memset(add, 0, sizeof add);    int now = 0;    for(int i = 1; i <= n; i++){        now += add[i];        b[i] += now;        if(b[i]<x){            int go = x - b[i];            b[i] += go;            m -= go;            now += go;            add[min(N-1,i+w)] -= go;            if(m<0)return false;        }    }    for(int i = n; i ; i--)        if(b[i]<x)return false;    return true;}int n, w, m;int main() {    while(~scanf("%d %d %d",&n,&m,&w)){        int minn = inf, maxx = 0;        for(int i = 1; i <= n; i++){            scanf("%d",&a[i]);            minn = min(minn, a[i]);            maxx = max(maxx, a[i]);        }        int ans = minn;        int l = minn, r = maxx + m;        while(l <= r){            int mid = (l+r)>>1;            if(ok(mid, n, m, w))                ans = max(ans, mid), l = mid+1;            else                 r = mid-1;        }        printf("%d\n",ans);    }    return 0;}


0 0