[DP记录]AT2347 [ARC070C] NarrowRectangles
command_block · · 个人记录
题意 : 有
现在可以上下移动这些木板,使得所有木板连接起来(有一点接触就算连接)。问最小的移动距离和。
最小值位置变为
-
情况B :
c<L 查看
L 左侧的第一段斜率为-1 的区间,假设为[T,L] 。则新的最小值区间为
[\max(c,T),L] 。在左堆加入两个c ,因为斜率变化了两次。 -
情况C :
c>R 情况类似,查看
R 右侧的第一段斜率为1 的区间,假设为[R,T] 。则新的最小值区间为
[R,\min(c,T)] 。在右堆加入两个c 。
需要给堆维护一个加法标记。
还要考虑如何求解答案。记
-
情况A : 最小值不变。
-
情况B : 最小值加上
L-c -
情况C : 最小值加上
c-R
复杂度
#include<algorithm>
#include<cstdio>
#include<queue>
#define ll long long
#define MaxN 100500
using namespace std;
int n;ll len[MaxN];
priority_queue<ll> ql;
priority_queue<ll,vector<ll>,greater<ll> > qr;
int main()
{
ll x,tl=0,tr=0,ans=0;
scanf("%d%lld%lld",&n,&x,&len[1]);
len[1]-=x;ql.push(x);qr.push(x);
for (int i=2;i<=n;i++){
scanf("%d%d",&x,&len[i]);
len[i]-=x;
tl-=len[i];tr+=len[i-1];
ll L=ql.top()+tl,R=qr.top()+tr;
if (L<=x&&x<=R){ql.push(x-tl);qr.push(x-tr);}
else if (x<L){
ans+=L-x;
ql.pop();qr.push(L-tr);
ql.push(x-tl);ql.push(x-tl);
}else {
ans+=x-R;
qr.pop();ql.push(R-tl);
qr.push(x-tr);qr.push(x-tr);
}
}printf("%lld",ans);
return 0;
}