[TJOI2013]松鼠聚會

傳送門

題意爲給定一些點,選其中一個點使其他點到這個點的切比雪夫距離之和最小,求出最小距離。

切比雪夫距離=max(Δx,Δy)\max(\Delta x,\Delta y),因爲取maxmax不太好優化,我們可以把它轉化爲曼哈頓距離(Δx+Δy)(\Delta x+\Delta y)來做。

(x,y)(x,y)變爲(x+y2,xy2)(\frac{x+y}2,\frac{x−y}2) 後,原座標系中的切比雪夫距離==新座標系中的曼哈頓距離

(x,y)(x,y)變爲(x+y,xy)(x+y,x−y)後,原座標系中的曼哈頓距離==新座標系中的切比雪夫距離

如果x,yx,y數組都是有序的,那麼

ansx=j=1nΔ(j,i)ans_x=\sum ^{n}_{j=1}\Delta(j,i)

=Δx(1,i)+Δx(2,i)+Δx(3,i)+...+Δx(n,i)=\Delta x(1,i)+\Delta x(2,i)+\Delta x(3,i)+...+\Delta x(n,i)

=(xix1)+(xix2)+...+(xixi1)+(xi+1xi)+(xi+2xi)+(xnxi)=(x_i-x_1)+(x_i-x_2)+...+(x_i-x_{i-1})+(x_{i+1}-x_i)+(x_{i+2}-x_i)+(x_n-x_i)

=j=1i1(xixj)+j=i+1n(xjxi)=\sum_{j=1}^{i-1}(x_i-x_j)+\sum_{j=i+1}^n(x_j-x_i)

=j=1nxj2×j=1ixjxi×(n2×i)=\sum_{j=1}^n x_j-2\times\sum_{j=1}^i x_j-x_i\times(n-2\times i)

然後就用前綴和優化一下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
	return x*f;
}
struct A{ll x,y;}a[N];ll x[N],y[N],s1[N],s2[N],ans=1ll<<62;int n,p,u,v;
int main(){
	n=read();
	for(int i=1;i<=n;++i) u=read(),v=read(),a[i].x=x[i]=u+v,a[i].y=y[i]=u-v;
	sort(x+1,x+n+1);sort(y+1,y+n+1);
	for(int i=1;i<=n;++i) s1[i]=s1[i-1]+x[i],s2[i]=s2[i-1]+y[i];
	for(int i=1;i<=n;++i){
        ll tmp=0;
        p=lower_bound(x+1,x+n+1,a[i].x)-x;tmp+=s1[n]-2*s1[p]-a[i].x*(n-2*p);
        p=lower_bound(y+1,y+n+1,a[i].y)-y;tmp+=s2[n]-2*s2[p]-a[i].y*(n-2*p);
        ans=min(ans,tmp);
	}return !printf("%lld",ans>>1);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章