[Codeforces 460C] Present
[题目链接]
https://codeforces.com/contest/460/problem/C
[算法]
二分 + 贪心
要求最小值最大 , 我们不妨二分最小值 , 若一盆花的高度小于二分的值 , 则将这盆花起的w盆花的高度都加一 , 具体实现时可以使用前缀和 + 差分
时间复杂度 : O(NlogV)
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; const int inf = 2e9; int n , m , w; int a[MAXN]; template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline bool check(int mid) { int cnt = 0; static int delta[MAXN]; for (int i = 1; i <= n; i++) delta[i] = 0; for (int i = 1; i <= n; i++) { delta[i] += delta[i - 1]; while (a[i] + delta[i] < mid) { if (++cnt > m) return false; delta[i]++; delta[min(i + w,n + 1)]--; } } return true; } int main() { read(n); read(m); read(w); int l = inf , r = 0; for (int i = 1; i <= n; i++) { read(a[i]); l = min(l,a[i]); r = max(r,a[i]); } r += m; int ans = l; while (l <= r) { int mid = (l + r) >> 1; if (check(mid)) { ans = mid; l = mid + 1; } else r = mid - 1; } printf("%d\n",ans); return 0; }