新技能get!感谢杰神指导!
题意:
给你一个序列,每次你能让连续的w个值+1,你最多只能执行m次这样的操作。让你使得m次操作后最小值最大。
思路:
最小最大值,二分。
但怎么维护一个序列?可以开这样的一个数组。
s[1]:表示1到序列最后都要加上s[1];
每次只能让连续的w个值+1,因此s[1+w] = - s[1];
AC代码:
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1e5 + 5;
const int INF = 0x3f3f3f3f;
int s[MAXN]; //weihu array
int a[MAXN], re[MAXN];
int n, m, w;
bool OK(int mid)
{
for(int i = 0;i < n; i++)
re[i+1] = mid-a[i];
//
int rm = m;
memset(s, 0, sizeof(s));
for(int i = 1;i <= n && rm >= 0; i++)
{
s[i] += s[i-1];
re[i] += s[i];
if(re[i] <= 0) continue;
rm -= re[i];
s[i] -= re[i];
if(i+w <= n) s[i+w] += re[i];
}
if(rm < 0) return false;
return true;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m>>w;
int tmax = 0;
for(int i = 0;i < n; i++)
{
cin>>a[i];
tmax = max(a[i], tmax);
}
//
int l = 1, r = m+tmax, res = 0;
while(l <= r)
{
int mid = (l+r)/2;
if(OK(mid))
{
res = mid;
l = mid+1;
}
else
{
r = mid-1;
}
}
cout<<res<<endl;
return 0;
}