题解 P3964 【[TJOI2013]松鼠聚会】

quantum11

2018-12-04 15:30:00

Solution

题意为给定一些点,选其中一个点使其他点到这个点的切比雪夫距离之和最小,求出最小距离。 切比雪夫距离=$\max(\Delta x,\Delta y)$,因为取$max$不太好优化,我们可以把它转化为曼哈顿距离$(\Delta x+\Delta y)$来做。 将$(x,y)$变为$(\frac{x+y}2,\frac{x−y}2)$ 后,原坐标系中的切比雪夫距离$=$新坐标系中的曼哈顿距离 将$(x,y)$变为$(x+y,x−y)$后,原坐标系中的曼哈顿距离$=$新坐标系中的切比雪夫距离 如果$x,y$数组都是有序的,那么 $$ans_x=\sum ^{n}_{j=1}\Delta(j,i)$$ $$=\Delta x(1,i)+\Delta x(2,i)+\Delta x(3,i)+...+\Delta x(n,i)$$ $$=(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)$$ $$=\sum_{j=1}^{i-1}(x_i-x_j)+\sum_{j=i+1}^n(x_j-x_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); } ```