首先我们发现,在这题中上下左右斜八个方向的距离被定义为相等的,那么大概就是这样:
那么两点之间的距离实际上是一个切比雪夫距离。
切比雪夫距离表示如下:
因为坐标的范围敲大,所以我们并不能直接使用切比雪夫距离。
那么我们有一个距离计算方式可以解决这个问题,那么就是曼哈顿距离:
为什么呢?因为他的横纵坐标是分开的,那么我们可以通过前缀和和后缀和来计算出距离和。
首先计算横坐标,先按横坐标排序,对于在i个点首先继承前缀和,然后前面i-1个点的距离都要加上(a[i].x-a[i-1].x),然后计算后面的点到他的距离和,所以要在做一遍后缀和,纵坐标同理。
那么我们要如何转化他们呢?首先看一下曼哈顿距离转化为切比雪夫距离:
dis=|x1−x2|+|y1−y2|
d
i
s
=
|
x
1
−
x
2
|
+
|
y
1
−
y
2
|
∵|x1−x2|=max(x1−x2,x2−x1)
∵
|
x
1
−
x
2
|
=
m
a
x
(
x
1
−
x
2
,
x
2
−
x
1
)
∴dis=max(x1−x2+y1−y2,x2−x1+y1−y2,x1−x2+y2−y1,x2−x1+y2−y1)
∴
d
i
s
=
m
a
x
(
x
1
−
x
2
+
y
1
−
y
2
,
x
2
−
x
1
+
y
1
−
y
2
,
x
1
−
x
2
+
y
2
−
y
1
,
x
2
−
x
1
+
y
2
−
y
1
)
=max((x1+y1)−(x2+y2),−(x1−y1)+(x2−y2),(x1−y1)−(x2−y2),−(x1+y1)+(x2+y2))
=
m
a
x
(
(
x
1
+
y
1
)
−
(
x
2
+
y
2
)
,
−
(
x
1
−
y
1
)
+
(
x
2
−
y
2
)
,
(
x
1
−
y
1
)
−
(
x
2
−
y
2
)
,
−
(
x
1
+
y
1
)
+
(
x
2
+
y
2
)
)
设X=x+y,Y=x−y
设
X
=
x
+
y
,
Y
=
x
−
y
则dis=max(X1−X2,Y2−Y1,Y1−Y2,X2−X1)
则
d
i
s
=
m
a
x
(
X
1
−
X
2
,
Y
2
−
Y
1
,
Y
1
−
Y
2
,
X
2
−
X
1
)
=max(|X1−X2|,|Y1−Y2|)
=
m
a
x
(
|
X
1
−
X
2
|
,
|
Y
1
−
Y
2
|
)
看吧,这样就转换成了切比雪夫距离。
那么我们如何吧切比雪夫距离转换成曼哈顿距离呢?只要把上面的运算倒过来
dis=max(|x1−x2|,|y1−y2|)
d
i
s
=
m
a
x
(
|
x
1
−
x
2
|
,
|
y
1
−
y
2
|
)
=max(x1−x2,x2−x1,y1−y2,y2−y1)⋅⋅⋅⋅①
=
m
a
x
(
x
1
−
x
2
,
x
2
−
x
1
,
y
1
−
y
2
,
y
2
−
y
1
)
·
·
·
·
①
设X=x+y,Y=x−y
设
X
=
x
+
y
,
Y
=
x
−
y
则X1=x1+y1,Y1=x1−y1,X2=x2+y2,Y3=x2−y2
则
X
1
=
x
1
+
y
1
,
Y
1
=
x
1
−
y
1
,
X
2
=
x
2
+
y
2
,
Y
3
=
x
2
−
y
2
x1=X1+Y12,y1=X1−Y12
x
1
=
X
1
+
Y
1
2
,
y
1
=
X
1
−
Y
1
2
x2=X2+Y22,y2=X2−Y22
x
2
=
X
2
+
Y
2
2
,
y
2
=
X
2
−
Y
2
2
带入①式得
dis=max(X1−X2+Y1−Y22,X2−X1+Y1−Y22,X1−X2+Y2−Y12,X2−X1+Y2−Y12)
d
i
s
=
m
a
x
(
X
1
−
X
2
+
Y
1
−
Y
2
2
,
X
2
−
X
1
+
Y
1
−
Y
2
2
,
X
1
−
X
2
+
Y
2
−
Y
1
2
,
X
2
−
X
1
+
Y
2
−
Y
1
2
)
∴2∗dis=max(X1−X2+Y1−Y2,X2−X1+Y1−Y2,X1−X2+Y2−Y1,X2−X1+Y2−Y1)
∴
2
∗
d
i
s
=
m
a
x
(
X
1
−
X
2
+
Y
1
−
Y
2
,
X
2
−
X
1
+
Y
1
−
Y
2
,
X
1
−
X
2
+
Y
2
−
Y
1
,
X
2
−
X
1
+
Y
2
−
Y
1
)
又∵|x1−x2|=max(x1−x2,x2−x1)
又
∵
|
x
1
−
x
2
|
=
m
a
x
(
x
1
−
x
2
,
x
2
−
x
1
)
所以2∗dis=|X1−X2|+|Y1−Y2|
所
以
2
∗
d
i
s
=
|
X
1
−
X
2
|
+
|
Y
1
−
Y
2
|
即dis=|X1−X2|+|Y1−Y2|2
即
d
i
s
=
|
X
1
−
X
2
|
+
|
Y
1
−
Y
2
|
2
因为精度问题所以我们先按2*dis来搞,最后ans/2。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=100010;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct point
{
ll x,y;
int id;
}a[N]; ll w[N];
bool cmp1(point a,point b){return a.x<b.x;}
bool cmp2(point a,point b){return a.y<b.y;}
ll s[N],d[N];//前缀和,后缀和
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
{
ll x=read(),y=read();
a[i].x=(x+y),a[i].y=(x-y);
a[i].id=i;
}
sort(a+1,a+n+1,cmp1);
s[0]=0; for(int i=1;i<=n;i++) s[i]=s[i-1]+(a[i].x-a[i-1].x)*(i-1);
d[n+1]=0; for(int i=n;i>=1;i--) d[i]=d[i+1]+(a[i+1].x-a[i].x)*(n-i);
for(int i=1;i<=n;i++) w[a[i].id]+=s[i]+d[i];
sort(a+1,a+n+1,cmp2);
s[0]=0; for(int i=1;i<=n;i++) s[i]=s[i-1]+(a[i].y-a[i-1].y)*(i-1);
d[n+1]=0; for(int i=n;i>=1;i--) d[i]=d[i+1]+(a[i+1].y-a[i].y)*(n-i);
for(int i=1;i<=n;i++) w[a[i].id]+=s[i]+d[i];
ll maxx=1LL<<63-1;
for(int i=1;i<=n;i++) maxx=min(maxx,w[i]);
printf("%lld\n",maxx>>1);
return 0;
}