前置知识
解法
将切比雪夫距离转换成曼哈顿距离,有新坐标为 \((\frac{x_{i}+y_{i}}{2},\frac{x_{i}-y_{i}}{2})\),因带一个 \(\frac{1}{2}\) 的常数不妨提出来得到 \((x_{i}'=x_{i}+y_{i},y_{i}'=x_{i}-y_{i})\) 最后统一乘起来。
此时切比雪夫坐标系里 \((x,y)\) 向上/右走分别对应曼哈顿坐标系里走到 \((x+1,y+1)/(x+1,y-1)\),即走路斜率对应 \(1/-1\)。
将所有点按照横坐标排序后,设 \(f_{i,j}\) 表示处理第 \(i\) 个点时纵坐标为 \(j\) 时的最小花费,状态转移方程为 \(f_{i,j}=\min\limits_{k=j-(x_{i}'-x_{i-1}')}^{j+(x_{i}'-x_{i-1}')}\{ f_{i-1,k} \} +|j-y_{i}'|\),使用 Slope Trick 优化即可,做法和 [ABC217H] Snuketoon 基本类似。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
pair<ll,ll>a[800010];
priority_queue<ll,vector<ll>,less<ll> >l;
priority_queue<ll,vector<ll>,greater<ll> >r;
int main()
{
// #define Isaac
#ifdef Isaac
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
ll n,ans=0,x,y,lazyl=0,lazyr=0,i;
cin>>n;
for(i=1;i<=n;i++)
{
cin>>x>>y;
a[i].first=x+y;
a[i].second=x-y;
l.push(0);
r.push(0);
}
sort(a+1,a+1+n);
for(i=1;i<=n;i++)
{
lazyl-=a[i].first-a[i-1].first;
lazyr+=a[i].first-a[i-1].first;
if(a[i].second<l.top()+lazyl)
{
ans+=(l.top()+lazyl)-a[i].second;
r.push(l.top()+lazyl-lazyr);
l.pop();
l.push(a[i].second-lazyl);
l.push(a[i].second-lazyl);
}
else
{
if(a[i].second>r.top()+lazyr)
{
ans+=a[i].second-(r.top()+lazyr);
l.push(r.top()+lazyr-lazyl);
r.pop();
r.push(a[i].second-lazyr);
r.push(a[i].second-lazyr);
}
else
{
l.push(a[i].second-lazyl);
r.push(a[i].second-lazyr);
}
}
}
cout<<ans/2<<endl;
return 0;
}
标签:lazyr,题解,比雪夫,long,second,push,New,Beginning,define
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18634238