• BZOJ2458: [BeiJing2011]最小三角形


    BZOJ2458: [BeiJing2011]最小三角形

    https://lydsy.com/JudgeOnline/problem.php?id=2458

    分析:

    • 求最近点次近点更新答案能A掉这道题,虽然我不知道是不是正确的。
    • 那么用(KDtree)乱搞即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    typedef double f2;
    #define N 200050
    #define db(x) cerr<<#x<<" = "<<x<<endl
    #define ls ch[p][0]
    #define rs ch[p][1]
    int now;
    struct Point {
    	ll p[2];
    	Point() {p[0]=p[1]=0;}
    	Point(ll x_,ll y_) {p[0]=x_,p[1]=y_;}
    	bool operator < (const Point &u) const {
    		return p[now]==u.p[now] ? p[!now] < u.p[!now] : p[now] < u.p[now];
    	}
    }a[N];
    int n,ch[N][2],mx[N][2],mn[N][2],root;
    void pushup(int p,int x) {
    	mn[p][0]=min(mn[p][0],mn[x][0]);
    	mn[p][1]=min(mn[p][1],mn[x][1]);
    	mx[p][0]=max(mx[p][0],mx[x][0]);
    	mx[p][1]=max(mx[p][1],mx[x][1]);
    }
    int build(int l,int r,int flg) {
    	int mid=(l+r)>>1,p=mid;
    	now=flg;
    	nth_element(a+l,a+mid,a+r+1);
    	mx[p][0]=mn[p][0]=a[p].p[0];
    	mx[p][1]=mn[p][1]=a[p].p[1];
    	if(l<mid) ls=build(l,mid-1,flg^1),pushup(p,ls);
    	if(r>mid) rs=build(mid+1,r,flg^1),pushup(p,rs);
    	return p;
    }
    int p1,p2;
    ll s1,s2;
    ll pf(ll x) {return x*x;}
    ll calc(const Point &p1,const Point &p2) {return pf(p1.p[0]-p2.p[0])+pf(p1.p[1]-p2.p[1]);}
    ll F(int x,int p) {
    	if(a[p].p[0]>=mn[x][0]&&a[p].p[0]<=mx[x][0]&&a[p].p[1]>=mn[x][1]&&a[p].p[1]<=mx[x][1]) return 0;
    	if(a[p].p[0]>=mn[x][0]&&a[p].p[0]<=mx[x][0]) {
    		return min(pf(mn[x][1]-a[p].p[1]),pf(mx[x][1]-a[p].p[1]));
    	}
    	if(a[p].p[1]>=mn[x][1]&&a[p].p[1]<=mx[x][1]) {
    		return min(pf(mn[x][0]-a[p].p[0]),pf(mx[x][0]-a[p].p[0]));
    	}
    	return min(calc(a[p],Point(mn[x][0],mn[x][1])),min(calc(a[p],Point(mn[x][0],mx[x][1])),min(calc(a[p],Point(mx[x][0],mn[x][1])),calc(a[p],Point(mx[x][0],mx[x][1])))));
    }
    void query(int p,int id) {
    	ll t=calc(a[p],a[id]);
    	if(p!=id&&(!p1||t<s1)) {
    		s1=t; p1=p;
    	}
    	ll dls=ls?F(ls,id):1ll<<62;
    	ll drs=rs?F(rs,id):1ll<<62;
    	if(dls<drs) {
    		if(dls<s1) query(ls,id);
    		if(drs<s1) query(rs,id);
    	}else {
    		if(drs<s1) query(rs,id);
    		if(dls<s1) query(ls,id);
    	}
    }
    void query2(int p,int id) {
    	ll t=calc(a[p],a[id]);
    	if(p!=id&&p!=p1&&(!p2||t<s2)) {
    		s2=t; p2=p;
    	}
    	ll dls=ls?F(ls,id):1ll<<62;
    	ll drs=rs?F(rs,id):1ll<<62;
    	if(dls<drs) {
    		if(dls<s2) query2(ls,id);
    		if(drs<s2) query2(rs,id);
    	}else {
    		if(drs<s2) query2(rs,id);
    		if(dls<s2) query2(ls,id);
    	}
    }
    int main() {
    	scanf("%d",&n);
    	int i;
    	for(i=1;i<=n;i++) scanf("%lld%lld",&a[i].p[0],&a[i].p[1]);
    	root=build(1,n,0);
    	f2 ans=1e10;
    	for(i=1;i<=n;i++) {
    		p1=p2=0; s1=s2=1ll<<62;
    		query(root,i);
    		query2(root,i);
    		ans=min(ans,sqrt(s1)+sqrt(s2)+sqrt(calc(a[p1],a[p2])));
    	}
    	printf("%.6f
    ",ans);
    }
    
  • 相关阅读:
    zabbix+grafana使用
    其它工具网址
    IntelliJ IDEA 进行多线程调试
    mac外接显示器 双屏同时滑动问题
    wacher和acl
    zookeeper介绍
    iterm2用法与技巧
    linux下ssh公钥验证的设置和远程登录
    不变模式
    单例模式创建的三种方式
  • 原文地址:https://www.cnblogs.com/suika/p/10264101.html
Copyright © 2020-2023  润新知