• P3964 [TJOI2013]松鼠聚会


    传送门

    首先题意就是求一个点到所有其他点的切比雪夫距离和最小

    考虑枚举所有点作为答案,那么我们需要快速计算切比雪夫距离和,发现不太好算

    根据一些奇怪的套路,我们把坐标系变化,把 $(x,y)$ 变成 $(frac {x+y} {2} , frac {x-y} {2} )$

    这样搞以后,原本坐标系的切比雪夫距离就变成了新坐标系的曼哈顿距离

    求一群点到一个点 $(x',y')$ 的曼哈顿距离可以把距离分成 $x,y$ 考虑,

    对于 $x$,所有 $x$ 小于 $x'$ 的点对答案的贡献是 $(x'-x)$ ,大于 $x'$ 的点对答案的贡献是 $(x-x')$

    把 $x,x'$ 分开,然后对于小于 $x'$ 的点可以直接前缀和优化求 $sum-x$ ,最后加上 $sum x'$

    大于 $x'$ 的也是同理,$y$ 的情况也是同理

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int 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<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e5+7;
    const ll INF=1e18;
    int n;
    ll x[N],y[N],bx[N],by[N],sx[N],sy[N],ans=INF;
    inline ll work(int x,int y)
    {
        ll res=0;
        int px=lower_bound(bx+1,bx+n+1,x)-bx;
        int py=lower_bound(by+1,by+n+1,y)-by;
        res+=1ll*x*px-sx[px]; res+=1ll*y*py-sy[py];
        res+=sx[n]-sx[px]-1ll*x*(n-px);
        res+=sy[n]-sy[py]-1ll*y*(n-py);
        return res;
    }
    int main()
    {
        n=read(); int a,b;
        for(int i=1;i<=n;i++)
        {
            a=read(),b=read();
            x[i]=a+b; y[i]=a-b;
            bx[i]=x[i]; by[i]=y[i];
        }
        sort(bx+1,bx+n+1); sort(by+1,by+n+1);
        for(int i=1;i<=n;i++) sx[i]=sx[i-1]+bx[i];
        for(int i=1;i<=n;i++) sy[i]=sy[i-1]+by[i];
        for(int i=1;i<=n;i++)
            ans=min(ans,work(x[i],y[i]));
        printf("%lld
    ",ans/2);
    }
  • 相关阅读:
    SVN安装
    清楚OpenGL代码中的列主矩阵和行主矩阵
    UVA-122(Trees on the level)
    POJ
    POJ-1797(Heavy Transportation)
    POJ
    POJ
    最短路经---SPFA算法
    POJ
    HDU
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11510678.html
Copyright © 2020-2023  润新知