zoukankan      html  css  js  c++  java
  • BZOJ2458 Beijing2011最小三角形(分治)

      类似于平面最近点对,考虑分治,即分别计算分割线两侧的最小三角形再考虑跨过线的三角形。

      复杂度证明也是类似的,对于某一个点,在另一侧可能与其构成最小三角形的点在一个d*d/2的矩形内(两边之和大于第三边),并且这些点所组成的三角形周长均不小于d。然而并不清楚这里至多会有多少个点,vfk曾说上界是16,我当然不会证明这个上界也构造不出来有这么多点的方案。找这些点的时候归并就可以做到线性。那么复杂度是O(nlogn)乘上枚举这些点的常数2*16*15/2,看起来根本跑不动不过这个上界肯定是特别松的所以一点也不虚。

      算距离的时候会爆int。以及luogu数据疑似有锅。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 200010
    #define inf 1000000000
    int n;
    double ans=inf;
    struct data
    {
        int x,y;
        bool operator <(const data&a) const
        {
            return x<a.x||x==a.x&&y<a.y;
        }
        double operator -(const data&a) const
        {
            return sqrt(1ll*(x-a.x)*(x-a.x)+1ll*(y-a.y)*(y-a.y));
        }
    }a[N],b[N],c[N];
    void getans(data *b,data *c,int n,int m)
    {
        int s=1,t=0;
        for (int i=1;i<=n;i++)
        {
            while (s<=m&&c[s].y+ans/2<b[i].y) s++;
            while (t<m&&c[t+1].y-ans/2<b[i].y) t++;
            for (int j=s;j<t;j++)
            {
                double tot=b[i]-c[j];
                for (int k=j+1;k<=t;k++)
                ans=min(ans,tot+(c[k]-b[i])+(c[k]-c[j]));
            }
        }
    }
    void solve(int l,int r)
    {
        if (l==r) return;
        int mid=l+r>>1;
        solve(l,mid);
        solve(mid+1,r);
        int n=0,m=0,MID=-inf;
        for (int i=l;i<=mid;i++) MID=max(MID,a[i].x);
        for (int i=l;i<=mid;i++)
        if (2*(MID-a[i].x)<ans) b[++n]=a[i];
        for (int i=mid+1;i<=r;i++)
        if (2*(a[i].x-MID)<ans) c[++m]=a[i];
        getans(b,c,n,m);
        getans(c,b,m,n);
        int i=l,j=mid+1;
        for (int k=l;k<=r;k++)
        if (j>r||i<=mid&&a[i].y<a[j].y) b[k]=a[i++];
        else b[k]=a[j++];
        for (int k=l;k<=r;k++) a[k]=b[k];
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2458.in","r",stdin);
        freopen("bzoj2458.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
        sort(a+1,a+n+1);
        solve(1,n);
        printf("%.6lf",ans);
        return 0;
    }
  • 相关阅读:
    20210110-正则表达式
    20210105
    C# Expression 树转化为SQL语句(一)
    5000行js db
    Keras智能
    nginx 设置多个tcp IP代理 socket 转发
    FTP连接时出现“227 Entering Passive Mode” 的解决方法
    windows nginx TCP代理 负载均衡
    nginx 代理ftp
    Intellij IDEA添加项目依赖
  • 原文地址:https://www.cnblogs.com/Gloid/p/9574244.html
Copyright © 2011-2022 走看看