题目大意:K维空间内,与给定点欧几里得距离最近的 m 个点。

  KD树啊……还能怎样啊……然而扩展到k维其实并没多么复杂?除了我已经脑补不出建树过程……不过代码好像变化不大>_>

  然而我WA了。。。为什么呢。。。我也不知道……

  一开始我的Push_up是这么写的:

inline void Push_up(int o){
    rep(i,k){
        if (L) t[o].mn[i]=min(t[o].mn[i],t[L].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[L].mx[i]);
        if (R) t[o].mx[i]=min(t[o].mn[i],t[R].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[R].mx[i]);
    }
}

  就是如果没有右儿子,就不用它更新了……

  然而我改成zyf的这样:(t[0]初始化一下,mn都置为INF,mx都置为-INF)

inline void Push_up(int o){
    rep(i,k){
        t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i]));
        t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i]));
    }
}

  就过了………………【BZOJ】【3053】The Closest M Points  【BZOJ】【3053】The Closest M Points

 

P.S.多组数据的题目,KD-Tree一定要记得清空 l 和 r ……要不然叶子节点会有一些奇怪的问题……

获得称号:

【BZOJ】【3053】The Closest M Points

  1 /**************************************************************
  2     Problem: 3053
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1364 ms
  7     Memory:9088 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 3053
 11 #include<queue>
 12 #include<cmath>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 #define sqr(x) ((x)*(x))
 23 using namespace std;
 24 typedef long long LL;
 25 inline int getint(){
 26     int r=1,v=0; char ch=getchar();
 27     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 28     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 29     return r*v;
 30 }
 31 const int N=100010,INF=1e9;
 32 /*******************template********************/
 33  
 34 int n,k,D,root,ans[15];
 35 struct node{
 36     int d[6],mn[6],mx[6],l,r;
 37     int& operator [] (int x){return d[x];}
 38     void read(){rep(i,k) d[i]=getint();}
 39 }t[N],tmp;
 40 bool operator < (node a,node b){return a[D]<b[D];}
 41 #define L t[o].l
 42 #define R t[o].r
 43 #define mid (l+r>>1)
 44 inline void Push_up(int o){
 45     rep(i,k){
 46         t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i]));
 47         t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i]));
 48     }
 49 }
 50 int build(int l,int r,int dir){
 51     D=dir;
 52     nth_element(t+l,t+mid,t+r+1);
 53     rep(i,k) t[mid].mn[i]=t[mid].mx[i]=t[mid][i];
 54     t[mid].l=l<mid ? build(l,mid-1,(dir+1)%k) : 0;
 55     t[mid].r=mid<r ? build(mid+1,r,(dir+1)%k) : 0;
 56     Push_up(mid);
 57     return mid;
 58 }
 59 inline int getdis(int o){
 60     if (!o) return INF;
 61     int ans=0;
 62     rep(i,k) if (tmp[i]<t[o].mn[i]) ans+=sqr(t[o].mn[i]-tmp[i]);
 63     rep(i,k) if (tmp[i]>t[o].mx[i]) ans+=sqr(tmp[i]-t[o].mx[i]);
 64     return ans;
 65 }
 66 inline int dis(node a,node b){
 67     int ans=0;
 68     rep(i,k) ans+=sqr(a[i]-b[i]);
 69     return ans;
 70 }
 71 typedef pair<int,int> pii;
 72 priority_queue<pii>Q;
 73 #define mp make_pair
 74 #define X first
 75 #define Y second
 76 void query(int o){
 77     int dl=getdis(L),dr=getdis(R),d0=dis(t[o],tmp);
 78     if (d0<Q.top().X){Q.pop(); Q.push(mp(d0,o));}
 79     if (dl<dr){
 80         if (dl<Q.top().X) query(L);
 81         if (dr<Q.top().X) query(R);
 82     }else{
 83         if (dr<Q.top().X) query(R);
 84         if (dl<Q.top().X) query(L);
 85     }
 86 }
 87 int main(){
 88 #ifndef ONLINE_JUDGE
 89     freopen("3053.in","r",stdin);
 90     freopen("3053.out","w",stdout);
 91 #endif
 92     rep(i,5) t[0].mn[i]=INF,t[0].mx[i]=-INF;
 93     while(scanf("%d%d",&n,&k)!=EOF){
 94         F(i,1,n) rep(j,k) t[i][j]=getint();
 95         root=build(1,n,0);
 96         int T=getint();
 97         while(T--){
 98             rep(j,k) tmp[j]=getint();
 99             n=getint();
100             printf("the closest %d points are:\n",n);
101             F(i,1,n) Q.push(mp(INF,0));
102             query(root);
103             D(i,n,1) ans[i]=Q.top().Y,Q.pop();
104             F(i,1,n) rep(j,k)
105                 printf("%d%c",t[ans[i]][j],j!=k-1?' ':'\n');
106         }
107     }
108     return 0;
109 }
View Code

相关文章: