分析
之前居然不知道有差分这东西¿¿
原来就是前缀和的逆,但是通常配合前缀和一起使用,多用于区间修改。先创建一个差分数组b,每次操作是对
(
l
,
r
)
(l, r)
(l,r)区间加上
c
c
c,就可以转换成对
b
[
l
]
+
=
c
,
b
[
r
+
1
]
−
=
c
b[l] += c, b[r + 1] -= c
b[l]+=c,b[r+1]−=c,然后再对b数组求一次前缀和,即可得到修改后的数组。
这题要枚举k
对于整个同侧的区间修改相对高度是不改变的,但是如果跨越k是可以作用于两侧的。
利用这一特性求差分进行贪心,差分是便于修改值。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,a[200010],b[200010];
long long x[200010],y[200010];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=2;i<=n;i++)
{
b[i]=a[i]-a[i-1];//差分
}
for(int i=2;i<=n;i++)
{
if(b[i]<=0) x[i]=x[i-1]-(b[i]-1);
else x[i]=x[i-1];
}
for(int i=n;i>=2;i--)
{
if(b[i]>=0) y[i]=y[i+1]+(b[i]+1);
else y[i]=y[i+1];
}
long long ans=1e18;
for(int i=1;i<=n;i++)
{
ans=min(ans,max(x[i],y[i+1]));
}
cout<<ans;
return 0;
}