Description

Little beaver is a beginner programmer, so informatics is his favorite subject. Soon his informatics teacher is going to have a birthday and the beaver has decided to prepare a present for her. He planted n flowers in a row on his windowsill and started waiting for them to grow. However, after some time the beaver noticed that the flowers stopped growing. The beaver thinks it is bad manners to present little flowers. So he decided to come up with some solutions.

There are m days left to the birthday. The height of the i-th flower (assume that the flowers in the row are numbered from 1 to n from left to right) is equal to ai at the moment. At each of the remaining m days the beaver can take a special watering and water w contiguous flowers (he can do that only once at a day). At that each watered flower grows by one height unit on that day. The beaver wants the height of the smallest flower be as large as possible in the end. What maximum height of the smallest flower can he get?

Solution

看加粗的部分,要使得最小高度的花的高度最大,经典的二分答案套路题。
每次二分答案,从左往右扫描,但目前高度小于答案时,必须要做一次区间加的操作。
区间加的操作可以用数据结构维护一下,我用的时差分数组。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5; 
ll a[N], b[N];
ll n, m, w;
bool check(ll x) {
    ll res = 0;
    memset(b, 0, sizeof(b));
    for(int i = 1; i <= n; i++) {
        b[i] = b[i - 1] + b[i];
        if(a[i] + b[i] < x) {
            ll num = x - (a[i] + b[i]);
            res += num; b[i] += num;
            if(i + w <= n) b[i + w] -= num;
            if(res > m) return false;
        }
    }
    return res <= m;
}
int main() {
    cin >> n >> m >> w;
    for(int i = 1; i <= n; i++) cin >> a[i];
    ll left = 1, right = 2e9;
    int ans = -1;
    while(left <= right) {
        ll mid = left + right >> 1;
        if(check(mid)) {
            ans = mid;
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    cout << ans << "\n";
    return 0;
}