题解:多维的估价跟二维一样,每一维的贡献跟二维的‘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;
}