传送门
题解:
令 t [ i ] = t [ i ] − i t[i]=t[i]-i t[i]=t[i]−i,那么 z z z就允许不严格递增,是个保序回归 L ∞ L_\infty L∞,可并堆维护一下中位数就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;T num;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs int N=1e6+7;
namespace LT{
int lc[N],rc[N],now;
int val[N],siz[N],d[N];
inline int merge(int u,int v){
if(!u||!v)return u|v;
if(val[u]<val[v])std::swap(u,v);
rc[u]=merge(rc[u],v);
siz[u]=siz[lc[u]]+siz[rc[u]]+1;
if(d[rc[u]]>d[lc[u]])std::swap(lc[u],rc[u]);
d[u]=d[rc[u]]+1;return u;
}
inline int top(int u){return val[u];}
inline int size(int u){return siz[u];}
inline void pop(int &u){u=merge(lc[u],rc[u]);}
inline int new_heap(int v){
val[++now]=v;siz[now]=1;
lc[now]=rc[now]=d[now]=0;
return now;
}
}
int cnt,n;
int L[N],R[N],rt[N],siz[N],a[N];
signed main(){
#ifdef zxyoi
freopen("sequence.in","r",stdin);
#endif
n=gi();
for(int re i=1;i<=n;++i){
++cnt;siz[cnt]=1;
rt[cnt]=LT::new_heap(a[i]=gi()-i);
L[cnt]=R[cnt]=i;
while(cnt>1&<::top(rt[cnt-1])>LT::top(rt[cnt])){
--cnt;
rt[cnt]=LT::merge(rt[cnt+1],rt[cnt]);
siz[cnt]+=siz[cnt+1];R[cnt]=R[cnt+1];
while(LT::size(rt[cnt])*2>siz[cnt]+1)LT::pop(rt[cnt]);
}
}
ll ans=0;
for(int re i=1;i<=cnt;++i)
for(int re j=L[i],t=LT::top(rt[i]);j<=R[i];++j)
ans+=abs(a[j]-t);
cout<<ans<<"\n";
return 0;
}