http://codeforces.com/contest/460/problem/C
二分查找,状态是否满足的判断,从前往后判断差值,与要判断的差值是多少,往后的这段w长度区间都增加多少,天数加1,判断最后会不会超过总天数。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define mem(a, b) memset (a, b, sizeof (a) )
#define reply(i, a, b, c) for (long long i = a; i <= b; i += c)
using namespace std;
const long long maxn = 500000+ 111;
const long long ef = (long long)1<<45;
long long n, m, w, minn;
long long a[maxn], b[maxn];
int solve (long long k) {
mem (b, 0);
long long temp = 0, cost = 0;
reply (i, 1, n, 1) {
temp += b[i];
long long tmp = k - (a[i] + temp);
if (tmp > 0) {
b[i+1] += tmp;
b[i+w] -= tmp;
cost += tmp;
}
}
return cost <= m;
}
void solve () {
long long l = 0, r = ef , ans = minn;
while (l <= r) {
long long m = (l + r) >> 1;
if (solve(m))
{
ans = max(ans, m);
l = m + 1;
}
else r = m -1;
}
cout<<ans<<endl;
}
int main() {
while (~scanf("%I64d%I64d%I64d",&n,&m,&w))
{
minn = ef;
reply (i, 1, n, 1) {
scanf ("%I64d", & a[i]);
minn = min (minn, a[i]);
}
solve();
}
return 0;
}