【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;
}
时间: 2024-10-31 03:21:26

【kd-tree】bzoj3053 The Closest M Points的相关文章

【BZOJ】3053: The Closest M Points(kdtree)

http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!!! 本题裸的kdtree,比上一题还要简单...................................... 对于当前点,判断进入左或右子树,然后看答案是否能过分割线..如果能,进入右或左子树.........并且如果答案个数小于k,也要进入.. 然后就浪吧........... #inc

【HDOJ】4347 The Closest M Points

居然是KD解. 1 /* 4347 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #i

【BZOJ3669】[Noi2014]魔法森林【Link-Cut Tree】【最小生成树】

[题目链接] 一开始写了个二分a+最短路b,骗了65分,然后改成二分b+最短路a,骗了70分..发现二分是不对的之后,给答案取min,骗到了90分.出题人太不负责任了. 正解是枚举a,用LCT维护b的最小生成树. /* Telekinetic Forest Guard */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 500

BZOJ3053 The Closest M Points

裸的KD-tree,还是在估计要不要进入子树的时候判断一下就好了,剩下都一样 判断的方法就是看现在答案个数是否小于k,和答案是否会经过分割线. 1 /************************************************************** 2 Problem: 3053 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:2164 ms 7 Memory:3572 kb 8 ************

bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】

传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOnline/problem.php?id=2581 这题我一看就知道自己不会了,只想了个O(2^n * 2 ^ n)即O(2 ^ 2n)的大暴力,也懒得打了,果断看solution. 看了之后惊呆了,看到了一种从未见过,闻所未闻的树叫做And-Or Tree,百度了一下,并没有官方中文翻译,姑且叫他"

【Same Tree】cpp

题目: Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 代码: /** * Definition for a binary tree node. * struct TreeNode

【poj2486】【Apple Tree】【树形dp】

Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7893 Accepted: 2642 Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of

【Symmetric Tree】cpp

题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree is symmetric: 1 / 2 2 / \ / 3 4 4 3 But the following is not: 1 / 2 2 \ 3 3 Note:Bonus points if you could solve it both

【hdu2815-Mod Tree】高次同余方程-拓展BadyStepGaintStep

http://acm.hdu.edu.cn/showproblem.php?pid=2815 题意:裸题... 题解:又有一个坑,就是N>=P的时候输出无解. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<cmath> 6 #include<algorithm> 7 using namespac