ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ-3170 [Tjoi2013]松鼠聚会(切比雪夫距离转曼哈顿距离)

2020-12-01 23:01:43  阅读:196  来源: 互联网

标签:frac limits int 比雪夫 距离 Tjoi2013 曼哈顿


题目描述

  草原上住着一群小松鼠,每个小松鼠都有一个家。时间长了,大家觉得应该聚一聚。但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理。

  每个小松鼠的家可以用一个点 \((x,y)\) 表示,两个点的距离定义为点 \((x,y)\) 和它周围的 \(8\) 个点 \((x-1,y),(x+1,y),(x,y-1),(x,y+1),(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)\) 距离为 \(1\)。

  数据范围:\(0\leq n\leq 10^5,-10^9\leq x,y\leq 10^9\)。

分析

  题意简述:在 \(n\) 个点中找到一个点 \(x\),使其他 \(n-1\) 个点到 \(x\) 的 切比雪夫距离 之和最小。求距离和的最小值。

  假设 \(A(x_1,y_1),B(x_2,y_2)\),\(A,B\) 两点的曼哈顿距离为:

\[\begin{align}d(A,B)&=|x_1-x_2|+|y_1-y_2|\\&=\max\{x_1-x_2+y_1-y_2,x_1-x_2+y_2-y_1,x_2-x_1+y_1-y_2,x_2-x_1+y_2-y_1\}\\&(把绝对值拆开,能够得到四个值,这四个值中的最大值是两个非负数之和,即曼哈顿距离)\\&=\max(|(x_1+y_1)|-(x_2+y_2)|,|(x_1-y_1)-(x_2-y_2)|)\end{align} \]

  容易发现,这就是 \((x_1+y_1,x_1-y_1),(x_2+y_2,x_2-y_2)\) 两点之间的切比雪夫距离。

  所以 将每一个点 \((x,y)\) 转化为 \((x+y,x-y)\),新坐标系下的切比雪夫距离即为原坐标系下的曼哈顿距离

  同理,\(A,B\) 两点的切比雪夫距离为:

\[d(A,B)=\max\{|x_1-x_2|,|y_1-y_2|\}=\Big|\frac{x_1+y_1}{2}-\frac{x_2+y_2}{2}\Big|+ \Big|\frac{x_1-y_1}{2}-\frac{x_2-y_2}{2} \Big| \]

  这就是 \(\big(\frac{x_1+y_1}{2},\frac{x_1-y_1}{2}\big),\big(\frac{x_2+y_2}{2},\frac{x_2-y_2}{2}\big)\) 两点之间的曼哈顿距离。

  所以 将每一个点 \((x,y)\) 转化为 \(\big(\frac{x+y}{2},\frac{x-y}{2}\big)\),新坐标系下的曼哈顿距离即为原坐标系下的切比雪夫距离

  回到本题,读入切比雪夫意义下的坐标并化为曼哈顿意义下的坐标,因为有除 \(2\) 可能有小数,先不除 \(2\),最后把距离除 \(2\) 是一样的。

  设 \(d(i,j)\) 为曼哈顿距离下点 \(i\) 到点 \(j\) 的曼哈顿距离。设当前枚举的终点为 \(j\),则 \(ans=\displaystyle\sum\limits_{i=1}^{n}d(i,j)\),时间复杂度为 \(O(n^2)\)。

  把和式展开:

\[\sum\limits_{i=1}^{n}d(i,j)=d(1,j)+d(2,j)+\cdots+d(n,j) \]

  取 $ d(i,j)$ 中的第一维坐标 \(|x_i-x_j|\) 化简:

\[\sum\limits_{i=1}^{n}\Delta x=|x_1-x_j|+|x_2-x_j|+\cdots+|x_j-x_j|+|x_{j+1}-x_j|+\cdots+|x_n-x_j| \]

  如果先将横坐标处理为递增的,可知 \(|x_j-x_j|\) 前面的式子一定可以拆绝对值化简,\(|x_{j+1}-x_j|\) 及以后的式子一定 \(\geq 0\),即:

\[\sum\limits_{i=1}^{n}\Delta x=\sum\limits_{i=1}^{j}(x_j-x_i)+\sum\limits_{i=j+1}^{n}(x_i-x_j) \]

  维护递增状态下 $x_i $ 和 \(y_i\) 的前缀和,\(\displaystyle\sum\limits_{i=1}^{j}x_j\) 直接使用 \(j\times x_j\) 计算即可。

  \(\text{dis}(i,j)\) 的第二维 \(\Delta y\) 可同理化简。

  也就是说,分别对 \(x_i,y_i\) 排序,处理成递增的序列。

  枚举每一个终点,把这个终点的横坐标 \(x_i\),纵坐标 \(y_i\) 在排好序的数组中的位置利用二分查找求出来,可以快速计算所有点到终点的距离之和。

  时间复杂度 \(O(n\log n)\)。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
const long long INF=2e18;
int n;
int x[N],y[N],tempx[N],tempy[N];
long long sumx[N],sumy[N];
long long solve(int i)
{
    int posx=lower_bound(tempx+1,tempx+1+n,x[i])-tempx;
    int posy=lower_bound(tempy+1,tempy+1+n,y[i])-tempy;
    return 1ll*posx*x[i]-sumx[posx]+sumx[n]-sumx[posx]-1ll*(n-posx)*x[i]+
           1ll*posy*y[i]-sumy[posy]+sumy[n]-sumy[posy]-1ll*(n-posy)*y[i];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int X,Y;
        scanf("%d%d",&X,&Y);//转化为曼哈顿距离意义下的坐标
        x[i]=tempx[i]=X+Y;//tempx与tempy是经过排序后得到的有序数组
        y[i]=tempy[i]=X-Y;//x与y存第i个点的坐标
    }
    sort(tempx+1,tempx+1+n);
    for(int i=1;i<=n;i++)
        sumx[i]=sumx[i-1]+tempx[i];
    sort(tempy+1,tempy+1+n);
    for(int i=1;i<=n;i++)
        sumy[i]=sumy[i-1]+tempy[i];
    long long ans=INF;
    for(int i=1;i<=n;i++)
        ans=min(ans,solve(i));
    printf("%lld\n",ans/2);
    return 0;
}

标签:frac,limits,int,比雪夫,距离,Tjoi2013,曼哈顿
来源: https://www.cnblogs.com/DestinHistoire/p/14071391.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有