【kd-tree】bzoj3053 The Closest M Points

同p2626。由于K比较小,所以不必用堆。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef double db;
#define N 50001
#define INF 2147483647.0
#define KD 5//ά¶ÈÊý
int qp[KD];
int n,root,kd,K;
int dn;
struct Ans
{
    int p[KD];
    db d;
}ans[10];
int sqr(const int &x){return x*x;}
struct Node
{
    int minn[KD],maxx[KD],p[KD];
    int ch[2];
    void Init()
      {
        for(int i=0;i<kd;++i)
          minn[i]=maxx[i]=p[i];
      }
    db Dis()
      {
        db t=0;
        for(int i=0;i<kd;++i)
          {
            t+=(db)sqr(max(0,minn[i]-qp[i]));
            t+=(db)sqr(max(0,qp[i]-maxx[i]));
          }
        return sqrt(t);
      }
}T[N<<1];
void Update(int rt)
{
    for(int i=0;i<2;++i)
      if(T[rt].ch[i])
        for(int j=0;j<kd;++j)
          {
            T[rt].minn[j]=min(T[rt].minn[j],T[T[rt].ch[i]].minn[j]);
            T[rt].maxx[j]=max(T[rt].maxx[j],T[T[rt].ch[i]].maxx[j]);
          }
}
db Dis(int a[],int b[])
{
    db t=0;
    for(int i=0;i<kd;++i)
      t+=(db)sqr(a[i]-b[i]);
    return sqrt(t);
}
bool operator < (const Node &a,const Node &b){return a.p[dn]<b.p[dn];}
int Buildtree(int l=1,int r=n,int d=0)
{
    dn=d;
    int m=(l+r>>1);
    nth_element(T+l,T+m,T+r+1);
    T[m].Init();
    if(l!=m) T[m].ch[0]=Buildtree(l,m-1,(d+1)%kd);
    if(m!=r) T[m].ch[1]=Buildtree(m+1,r,(d+1)%kd);
    Update(m);
    return m;
}
void Query(int rt=root)
{
    db t=Dis(T[rt].p,qp);
    for(int i=0;i<K;++i)
      if(t<ans[i].d)
        {
          for(int j=K-1;j>=i+1;--j)
            ans[j]=ans[j-1];
          ans[i].d=t;
          memcpy(ans[i].p,T[rt].p,sizeof(T[rt].p));
          break;
        }
    db dd[2];
    for(int i=0;i<2;i++)
      if(T[rt].ch[i])
        dd[i]=T[T[rt].ch[i]].Dis();
      else dd[i]=INF;
    bool f=(dd[0]<=dd[1]);
    if(dd[!f]<ans[K-1].d && T[rt].ch[!f]) Query(T[rt].ch[!f]);
    if(dd[f]<ans[K-1].d && T[rt].ch[f]) Query(T[rt].ch[f]);
}
int q;
int main()
{
//  freopen("bzoj3053.in","r",stdin);
//  freopen("bzoj3053.out","w",stdout);
    while(scanf("%d%d",&n,&kd)!=EOF)
      {
        for(int i=1;i<=n;++i)
          for(int j=0;j<kd;++j)
            scanf("%d",&T[i].p[j]);
        Buildtree();
        root=(1+n>>1);
        scanf("%d",&q);
        for(;q;--q)
          {
            for(int i=0;i<kd;++i)
              scanf("%d",&qp[i]);
            scanf("%d",&K);
            for(int i=0;i<K;++i)
              ans[i].d=INF;
            Query();
            printf("the closest %d points are:\n",K);
            for(int i=0;i<K;++i)
              {
                for(int j=0;j<kd-1;++j)
                  printf("%d ",ans[i].p[j]);
                printf("%d\n",ans[i].p[kd-1]);
              }
          }
        for(int i=1;i<=n;++i)
          T[i].ch[0]=T[i].ch[1]=0;
      }
    return 0;
}
posted @ 2015-06-18 21:42  AutSky_JadeK  阅读(122)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト