HDU 4347 The Closest M Points (kdTree)

赤果果的kdTree。

传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html

其实就是二叉树的变形

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4+6,K = 5;

#define squ(x) ((x)*(x))

int k,n,idx;

struct Point
{
    int x[K];
    bool operator <(const Point& rhs) const{
        return x[idx] < rhs.x[idx];
    }
    void print() const {
        for(int i = 0; i < k-1; i++)
            printf("%d ",x[i]);
        printf("%d\n",x[k-1]);
    }
}P[maxn];

#define fi first
#define se second
typedef pair<double,Point> HeapNode;
priority_queue<HeapNode> q;

struct kdTree
{
    Point Node[maxn<<2];
    int son[maxn<<2];
    #define lch (rt<<1)
    #define rch (rt<<1|1)

    void build(int l,int r,int rt = 1,int dep = 0)
    {
        if(l>r) return;
        son[rt] = r-l;
        int x = lch,y = rch;
        son[x] = son[y] = -1;
        idx = dep%k;
        int mid = (l+r)>>1;
        nth_element(P+l,P+mid,P+r+1);
        Node[rt] = P[mid];
        build(l,mid-1,x,dep+1);
        build(mid+1,r,y,dep+1);
    }

    Point qp; int qm;
    void query(int rt = 1,int dep = 0)
    {
        if(!~son[rt]) return;
        HeapNode u(0,Node[rt]);
        for(int i = 0; i < k; i++)
            u.fi += squ(u.se.x[i]-qp.x[i]);

        int dim = dep%k, x = lch, y = rch;
        bool flag = false;
        if(qp.x[dim]>=Node[rt].x[dim]) swap(x,y);
        if(~son[x]) query(x,dep+1);
        if(q.size()<qm) q.push(u),flag = true;
        else {
            if(u.fi<q.top().fi) q.pop(),q.push(u);
            if(squ(qp.x[dim]-Node[rt].x[dim])<q.top().fi) flag = true;
        }
        if(flag&&~son[y]) query(y,dep+1);
    }
}kd;

const int M = 11;
Point ans[M];

int main()
{
   // freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&k)){
        for(int i = 0; i < n; i++)
        for(int j = 0; j < k; j++)
            scanf("%d",&P[i].x[j]);
        kd.build(0,n-1);
        int t; scanf("%d",&t);
        while(t--){
            for(int i = 0; i < k; i++) scanf("%d",&kd.qp.x[i]);
            scanf("%d",&kd.qm);
            kd.query();
            printf("the closest %d points are:\n",kd.qm);
            int top = 0;
            while(q.size()){
                ans[++top] = q.top().se;
                q.pop();
            }
            while(top){
                ans[top].print();
                top--;
            }
        }
    }
    return 0;
}
时间: 2024-12-28 14:59:12

HDU 4347 The Closest M Points (kdTree)的相关文章

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

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

bzoj 3053 HDU 4347 : The Closest M Points kd树

bzoj 3053 HDU 4347 : The Closest M Points  kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差较大的维度分开(建树常数大)或者每一位轮换分割(询问常数大),后者更快也更好些,以后就果断写第二种了. #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using

HDU 4347 - The Closest M Points - [KDTree模板题]

本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4347 Problem Description The course of Software Design and Development Practice is objectionable. ZLC is facing a serious problem

数据结构(KD树):HDU 4347 The Closest M Points

The Closest M Points Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others)Total Submission(s): 3285    Accepted Submission(s): 1201 Problem Description The course of Software Design and Development Practice is objection

hdu 4347 The Closest M Points (kd树)

hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说,上代码 . 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <s

hdu 4717 The Moving Points(三分)

http://acm.hdu.edu.cn/showproblem.php?pid=4717 大致题意:给出每个点的坐标以及每个点移动的速度和方向.问在那一时刻点集中最远的距离在所有时刻的最远距离中最小. 比赛时一直以为是计算几何,和线段相交什么的有关.赛后队友说这是道三分,仔细想了想确实是三分,试着画画图发现它是一个凸性函数,存在一个最短距离.然后三分时间就可以了. #include <stdio.h> #include <iostream> #include <map&g

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or

hdu 4857 逆拓扑+大根堆(priority_queue)

题意:排序输出:在先满足定约束条件下(如 3必需在1前面,7必需在4前面),在满足:1尽量前,其次考虑2,依次.....(即有次约束). 开始的时候,只用拓扑,然后每次在都可以选的时候,优先考虑小的,其实没什么简单,如 图(3-->1,2)这样输出是2.3.1,正确应该是 3 1 2,因为 1要尽量前(都满足第一约束). 参考他人思路结合自己理解:因为这样的弊端就是没有考虑这种情况:图中:若我的"子孙"中,有的比你次优先,虽然现在我们都可以输出,但是要考虑我的子代,若我的子代有次

hdu 5349 MZL&#39;s simple problem(multiset)

代码: #include<set> #include<cstdio> using namespace std; multiset<int> st; int main() { int n; multiset<int>::iterator it; while(scanf("%d",&n)==1) { st.clear(); int k,num; for(int i=0; i<n; i++) { scanf("%d&qu