zoukankan      html  css  js  c++  java
  • KD-Tree

    终于学会了kd树不带插入的,做了一下三维空间最近点对,记录一下板子
    这道题不知道为什么不判断两坐标相同答案为0的情况,加上之后就wa

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    int n,root,D,K=3;
    struct Point{
    	double d[3];
    	friend bool operator < (const Point &a,const Point &b){
    		if(a.d[D]!=b.d[D]) return a.d[D]<b.d[D];
    		for(int i=0;i<K;i++) if(a.d[i]!=b.d[i]) return a.d[i]<b.d[i];
    	}
    };
    Point p[N];
    
    struct KDTree{
    	#define sqr(x) ((x)*(x))
    	Point p[N],minp[N],maxp[N];
    	int ls[N],rs[N];
    	
    	void pushup(int id){
    		if(ls[id]) for(int i=0;i<K;i++)
    			minp[id].d[i]=min(minp[id].d[i],minp[ls[id]].d[i]),
    			maxp[id].d[i]=max(maxp[id].d[i],maxp[ls[id]].d[i]);
    		if(rs[id]) for(int i=0;i<K;i++)
    			minp[id].d[i]=min(minp[id].d[i],minp[rs[id]].d[i]),
    			maxp[id].d[i]=max(maxp[id].d[i],maxp[rs[id]].d[i]);
    	}
    	void build(int &id,int l,int r,int dd){
    		D=dd;
    		id=(l+r>>1);
    		nth_element(p+l,p+id,p+r+1);
    		minp[id]=p[id];maxp[id]=p[id];
    		if(id!=l) build(ls[id],l,id-1,(dd+1)%K);
    		if(id!=r) build(rs[id],id+1,r,(dd+1)%K);
    		pushup(id);
    	}
    	Point A;
    	double ans;
    	double getdis(int id){
    		double res=0;
    		for(int i=0;i<K;i++){
    			if(A.d[i]<minp[id].d[i]) res+=sqr(minp[id].d[i]-A.d[i]);
    			if(A.d[i]>maxp[id].d[i]) res+=sqr(maxp[id].d[i]-A.d[i]);
    		}
    		return res;
    	}
    	void ask(int id){
    		double d0=0;
    		for(int i=0;i<K;i++) d0+=sqr(p[id].d[i]-A.d[i]);
    		if(d0>0&&d0<ans) ans=d0;
    		double dl=(ls[id])?getdis(ls[id]):1e18;
    		double dr=(rs[id])?getdis(rs[id]):1e18;
    		if(dl<dr) 
    			{if(dl<ans) ask(ls[id]); if(dr<ans) ask(rs[id]);}
    		else
    			{if(dr<ans) ask(rs[id]); if(dl<ans) ask(ls[id]);}
    	}
    	double ask(Point _A){
    		A=_A;
    		ask(root);
    		return ans;
    	}
    }kdt;
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<K;j++)
    			scanf("%lf",&p[i].d[j]);
    	memcpy(kdt.p,p,sizeof(p));
    	kdt.build(root,1,n,0);
    	kdt.ans=1e18;
    	for(int i=1;i<=n;i++) kdt.ask(p[i]);
    	printf("%.3lf
    ",sqrt(kdt.ans));
    	return 0;
    }
    
  • 相关阅读:
    FFmpeg之cmdutils.h源码
    iOS文件操作一览
    ffmpeg结构体SpecifierOpt说明文档
    主要流媒体协议介绍
    HTTP Live Streaming直播(iOS直播)技术分析与实现(转)
    XCode快捷键总结
    ALAssetsLibrary获取相册列表
    iOS教程之ASIHttpRequest(源自51CTO.com)
    libxml/tree.h not found(XCode 4.5&5.1解决方案)
    MyBatis——Log4J(日志)
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/13985771.html
Copyright © 2011-2022 走看看