洛谷3964 [TJOI2013]松鼠聚会(切比雪夫转曼哈顿)

xiaoxiao2025-04-17  12

题意

求一个点,到所有点的切比雪夫距离之和最小。

题解

切比雪夫转曼哈顿+前缀和 显然切比雪夫不便于求和,因为它是一个max套在最外层,如果转为曼哈顿的形式就成了加加减减的问题了。 回忆一下转换公式:(x,y)->((x+y)/2,(x-y)/2) 答案是,关键是去绝对值符号,也就是。y同理。 不妨分开x和y来处理,把x和y分别排序,然后统计一波前缀和sx,sy。 枚举一个点(x0,y0),在x中找到比它小的数的个数px,大的自然可以知道n-px。此时x的距离就是sx[n]-sx[px]-(n-px)*a[i].x) + ((px-1)*a[i].x-sx[px-1]。y同理。

代码  

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int MAXN=100010; int n; struct U{ll x,y;}a[MAXN]; ll x[MAXN],y[MAXN]; ll sum=0,sx[MAXN],sy[MAXN]; int main() {     scanf("%d",&n);     for(int i=1;i<=n;i++)     {         ll X,Y;         scanf("%lld%lld",&X,&Y);         x[i]=X+Y;y[i]=X-Y;         a[i]=(U){x[i],y[i]};         sum+=x[i]+y[i];     }          sort(x+1,x+n+1);sort(y+1,y+n+1);     for(int i=1;i<=n;i++)     {         sx[i]=sx[i-1]+x[i];         sy[i]=sy[i-1]+y[i];     }          ll ans=1ll<<60;     for(int i=1;i<=n;i++)     {         int px=lower_bound(x+1,x+n+1,a[i].x)-x;         int py=lower_bound(y+1,y+n+1,a[i].y)-y;         ll tmp=(sx[n]-sx[px]-(n-px)*a[i].x) + ((px-1)*a[i].x-sx[px-1])               +(sy[n]-sy[py]-(n-py)*a[i].y) + ((py-1)*a[i].y-sy[py-1]);         ans=min(ans,tmp);     }     printf("%lld\n",ans/2);     return 0; }

 

转载请注明原文地址: https://www.6miu.com/read-5028488.html

最新回复(0)