P11598题解
happy_dengziyue · · 题解
1 思路
我们不必限制柱子的高度必须是整数,也不必限制必须是非负数。因为调整法可以证明如果柱子的高度不是非负整数就一定不优。
首先考虑动态规划。设
边界情况是
答案则为
直接计算这个式子显然是无法通过的。但是我们发现
再分析这个式子。可以化为对
第一个操作实际上是将常函数段左侧往左平移
可以考虑用两个优先队列分别维护常函数段左侧和常函数段右侧的折点,同时维护常函数段的值。
第一个操作只需要打个标记。第二个操作要分讨 V 形函数的顶点在常函数段横坐标范围里还是两侧,并修改常函数段横坐标范围;如果是两侧还需还需要计算常函数段的值的变化。
时间复杂度
2 代码与记录
#include<bits/stdc++.h>
using namespace std;
#define max_n 200000
#define inf ((long long)2e9)
int n;
long long lim;
long long a[max_n+2];
priority_queue<long long>ql;
priority_queue<long long,vector<long long>,greater<long long>>qr;
long long low=0;
long long tagl=0,tagr=0;
int main(){
#ifdef dzy
freopen("P11598_1.in","r",stdin);
freopen("P11598_1.out","w",stdout);
#endif
scanf("%d%lld",&n,&lim);
for(int i=1;i<=n;++i)scanf("%lld",a+i);
ql.push(-1); qr.push(inf); low=0;
for(int i=1;i<=n;++i){
tagl-=lim; tagr+=lim;
long long l=ql.top()+tagl,r=qr.top()+tagr;
// printf("l=%lld r=%lld low=%lld\n",l,r,low);
if(l<=a[i]&&a[i]<=r){ql.push(a[i]-tagl); qr.push(a[i]-tagr);}
else if(a[i]<l){
low+=l-a[i];
ql.push(a[i]-tagl); ql.push(a[i]-tagl);
qr.push(ql.top()+tagl-tagr); ql.pop();
}
else{
low+=a[i]-r;
qr.push(a[i]-tagr); qr.push(a[i]-tagr);
ql.push(qr.top()+tagr-tagl); qr.pop();
}
}
printf("%lld\n",low);
return 0;
}
记录传送门
By dengziyue