Codeforces Round #262 (Div. 2)C. Present
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?
Input
The first line contains space-separated integers n, m and w (1 ≤ w ≤ n ≤ 10^5; 1 ≤ m ≤ 10^5). The second line contains space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 10^9).
Output
Print a single integer — the maximum final height of the smallest flower.
Examples
inputCopy
6 2 3
2 2 2 2 1 1
outputCopy
2
inputCopy
2 5 1
5 8
outputCopy
9
Note
In the first sample beaver can water the last 3 flowers at the first day. On the next day he may not to water flowers at all. In the end he will get the following heights: [2, 2, 2, 3, 2, 2]. The smallest flower has height equal to 2. It's impossible to get height 3 in this test.
题意:有n朵花,每朵花高度按顺序给出,然后有m天,每天可以浇花一次,一次可以浇w朵连续的花,浇完后这w朵花高度+1,m天过后,最矮的花最高的高度能为多少。
题解:感觉这两个最就能让人联想到二分。这道题主要思路就是:二分 + 贪心 + 差分。
首先可以开一个区间去枚举这个高度,区间范围可以是 0 - m + 花中最高的花的高度,因为答案最大也只可能是最高的花被浇了m次。
重点还是check函数怎么写吧:
首先先差分一下每朵花的高度,因为差分后比较好维护这w朵花连续的增长,遍历1-n朵花,若当前第i朵花高度已经达到二分得到高度h,那么就不用进行浇花,直接看下一朵。
否则,将该花浇到h(前提有这么多天给你浇),然后连续的从第i朵 -> 第i + w - 1朵都会同时长高(差分维护)。
接着每一次都记录一下到第i朵花前(包括第i朵花),最矮花的高度minH,最后判断一下minH与二分得到的h的关系即可。
tips:把差分数组开大点,不然到后面可能会越界,因为w的范围太大,然后还有就是其实更新的i - > i + w - 1, 而不是i - > i + w,今天下午的时候就翻车了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
int a[N], d[N];
int n, m, w, maxH = 0;
int check(int h)
{
// cout << "h: " << h << endl;
int x = m; //临时浇花总天数
memset(d, 0, sizeof(d));
int minH = inf; //当前最矮的花的高度
for(int i = 1; i <= n; i++) //差分
d[i] = a[i] - a[i-1];
for(int i = 1; i <= n; i++)
{
d[i] += d[i-1]; //第i朵花目前高度
if(h <= d[i]) continue; //假如目前二分的h比当前花高度小则不需要浇花
//否则需要浇花
// cout << "天数: " << x << " ";
if(x < h - d[i]) return 0; //浇花天数不够
else
{
x -= (h - d[i]); //总天数减少
d[i+w] -= (h - d[i]); //差分思想(从i -> i + w - 1 都会增高h - d[i])
d[i] = h; //将此花浇到二分得到h的高度
}
// cout << "i = " << i << " " << d[i] << endl;
minH = min(minH, d[i]); //记录当前最矮的花的高度
}
// cout << "minH: " << minH << endl;
if(minH >= h) return 1;
else return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> m >> w;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
maxH = max(maxH, a[i]);
}
int l = 0, r = maxH + m;
while(l < r)
{
int mid = (l + r + 1) / 2;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
return 0;
}
此题来源:集训太累了,就随便找了一道题来肝,结果构思半天,找bug几小时,瞬间感觉人没了,明天还有一天,顶住,顶住,奥里给!

浙公网安备 33010602011771号