首页 > 代码库 > 【BZOJ3053】The Closest M Points KDtree 好模板一只【数组版!!!】

【BZOJ3053】The Closest M Points KDtree 好模板一只【数组版!!!】

题解:多维的估价跟二维一样,每一维的贡献跟二维的‘x’、‘y’完全相同。


真不明白不会的是怎么想的,有区别么?!!


细节:


妈蛋的多组数据!调了好久啊、

然后行末还不能有空格,否则PE


除去这些,我是1A。。

可惜没有“除去”这一说。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 50100
#define K 10
#define inf 0x3f3f3f3f
using namespace std;
int judge,n,m,q;
struct Point 
{
	int c[K];
	bool operator < (const Point &a)const{return c[judge]<a.c[judge];}
	int d(Point &a)
	{
		int ret=0;
		for(int i=0;i<m;i++)ret+=(c[i]-a.c[i])*(c[i]-a.c[i]);
		return ret;
	}
}P[N];
struct ANS
{
	int x;
	Point p;
	bool operator < (const ANS &a)const {return x<a.x;}
}ans[15];
struct KDT
{
	int son[N][2],cnt;
	Point c[N][2];
	void init()
	{
		cnt=0;
		memset(son,0,sizeof(son));
	}
	int newnode(Point &p){cnt++,c[cnt][0]=c[cnt][1]=p;return cnt;}
	void update(int f)
	{
		int i,s;
		if(son[f][0])
		{
			s=son[f][0];
			for(i=0;i<m;i++)
				c[f][0].c[i]=min(c[f][0].c[i],c[s][0].c[i]),
				c[f][1].c[i]=max(c[f][1].c[i],c[s][1].c[i]);
		}
		if(son[f][1])
		{
			s=son[f][1];
			for(i=0;i<m;i++)
				c[f][0].c[i]=min(c[f][0].c[i],c[s][0].c[i]),
				c[f][1].c[i]=max(c[f][1].c[i],c[s][1].c[i]);
		}
	}
	int mindis(int f,Point &p)
	{
		int ret=0,i;
		for(i=0;i<m;i++)
		{
			if(p.c[i]<c[f][0].c[i])ret+=(c[f][0].c[i]-p.c[i])*(c[f][0].c[i]-p.c[i]);
			else if(c[f][1].c[i]<p.c[i])ret+=(c[f][1].c[i]-p.c[i])*(c[f][1].c[i]-p.c[i]);
		}
		return ret;
	}
	int build(int l,int r,int jd=0)
	{
		int mid=l+r>>1,i;
		judge=jd;
		jd=jd+1>=m?jd-m+1:jd+1;
		nth_element(P+l,P+mid,P+r+1);
		int t=0;
		if(l<mid)t=build(l,mid-1,jd);
		int x=newnode(P[mid]);son[x][0]=t;
		if(mid<r)son[x][1]=build(mid+1,r,jd);
		update(x);
		return x;
	}
	void query(int f,Point &p,int rank)
	{
		int Dis[3],i;
		Dis[2]=P[f].d(p);
		if(ans[rank-1].x>Dis[2])ans[rank-1].x=Dis[2],ans[rank-1].p=P[f],sort(ans,ans+rank);

		Dis[0]=Dis[1]=0;
		if(son[f][0])Dis[0]=mindis(son[f][0],p);
		if(son[f][1])Dis[1]=mindis(son[f][1],p);
		int t=Dis[0]>Dis[1];
		if(son[f][t]&&Dis[t]<ans[rank-1].x)query(son[f][t],p,rank);
		t^=1;if(son[f][t]&&Dis[t]<ans[rank-1].x)query(son[f][t],p,rank);
	}
}kdt;
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k,root;
	Point x;
	while(~scanf("%d%d",&n,&m))
	{
		root=0;
		kdt.init();
		for(i=1;i<=n;i++)for(j=0;j<m;j++)scanf("%d",&P[i].c[j]);
		if(n)root=kdt.build(1,n);
		for(scanf("%d",&q);q--;)
		{
			for(i=0;i<m;i++)scanf("%d",&x.c[i]);scanf("%d",&k);
			for(i=0;i<15;i++)ans[i].x=inf;
			kdt.query(root,x,k);
			printf("the closest %d points are:\n",k);
			for(i=0;i<k;i++)
			{
				for(j=0;j<m-1;j++)printf("%d ",ans[i].p.c[j]);
				printf("%d\n",ans[i].p.c[m-1]);
			}
		}
	//	puts("");
	}
	return 0;
}


复制去Google翻译翻译结果

【BZOJ3053】The Closest M Points KDtree 好模板一只【数组版!!!】