KDTree模板,在m维空间中找最近的k个点,用的是欧几里德距离。

理解了好久,昨晚始终不明白那些“估价函数”,后来才知道分情况讨论,≤k还是=k,在当前这一维度距离过线还是不过线,过线则要继续搜索另一个子树。还有别忘了当前这个节点!

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define read(x) x=getint()
using namespace std;
typedef long long LL;
const int N = 50003;
const int inf = 0x7fffffff;
int getint() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * fh;
}
int n, m, root, D;
LL minn;
struct P {
int d[5], mx[5], mn[5], l, r, id;
P (): l(0), r(0), id(0) {};
int &operator [] (int x) {return d[x];}
bool operator < (P point) const {return d[D] < point[D];}
} T[N << 1], po[N];
priority_queue <pair <LL, int> > Q;
LL sqr(LL x) {return x * x;}
LL dis(P a, P b) {
LL ret = 0;
for(int i = 0; i < m; ++i) ret += sqr(a[i] - b[i]);
return ret;
}
void pushup(int x, int y) {
for(int i = 0; i < m; ++i)
T[x].mn[i] = min(T[x].mn[i], T[y].mn[i]),
T[x].mx[i] = max(T[x].mx[i], T[y].mx[i]);
}
int Build(int l, int r, int dd) {
D = dd; int mid = (l + r) >> 1; nth_element(po + l, po + mid, po + r + 1);
for(int i = 0; i < m; ++i)
T[mid].mn[i] = T[mid].mx[i] = T[mid].d[i] = po[mid].d[i];
T[mid].id = mid;
if (l < mid) T[mid].l = Build(l, mid - 1, (dd + 1) % m);
if (mid < r) T[mid].r = Build(mid + 1, r, (dd + 1) % m);
if (T[mid].l) pushup(mid, T[mid].l);
if (T[mid].r) pushup(mid, T[mid].r);
return mid;
}
void ask(int rt, int dd, P p, int k) {
int L = T[rt].l, R = T[rt].r;
if (p[dd] >= T[rt][dd]) swap(L, R);
if (L) ask(L, (dd + 1) % m, p, k);
bool pd = 0; LL di = dis(T[rt], p); minn = min(minn, di);
if (Q.size() < k) { Q.push(pair <LL, int> (di, rt)); pd = 1;}
else {
if (di < Q.top().first) Q.pop(), Q.push(make_pair(di, rt));
if (sqr(p[dd] - T[rt][dd]) < Q.top().first) pd = 1;
}
if (pd && R) ask(R, (dd + 1) % m, p, k);
}
int ans[N];
int main() {
while (~scanf("%d%d", &n, &m)) {
for(int i = 1; i <= n; ++i)
for(int j = 0; j < m; ++j)
read(po[i][j]);
memset(T, 0, sizeof(T));
root = Build(1, n, 0);
int qq; read(qq);
for(; qq; --qq) {
P p; int k;
for(int i = 0; i < m; ++i)
read(p[i]);
read(k);
printf("the closest %d points are:\n", k);
minn = inf; ask(root, 0, p, k);
while (!Q.empty()) {
ans[++ans[0]] = Q.top().second;
Q.pop();
}
for(; ans[0]; --ans[0])
for(int i = 0; i < m; ++i)
printf("%d%c", T[ans[ans[0]]][i]," \n"[i == m - 1]);
}
}
return 0;
}

我就是弱啊~~~

【BZOJ 3053】The Closest M Points的更多相关文章

  1. 【BZOJ】【3053】The Closest M Points

    KD-Tree 题目大意:K维空间内,与给定点欧几里得距离最近的 m 个点. KD树啊……还能怎样啊……然而扩展到k维其实并没多么复杂?除了我已经脑补不出建树过程……不过代码好像变化不大>_&g ...

  2. 【35.43%】【hdu 4347】The Closest M Points

    Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) Total Submissio ...

  3. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  4. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  5. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  6. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  7. 【hdu4347】The Closest M Points 【KD树模板】

    题意 一个k维空间,给出n个点的坐标,给出t个询问,每个询问给出一个点的坐标和一个m.对于每个询问找出跟这个点最接近的m个点 分析 kd树的模板题. #include <cstdio> # ...

  8. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  9. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

随机推荐

  1. NOIP水题合集[3/未完待续]

    NOIP2008pj传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球, ...

  2. 常见sql数据类型

    数值型类型 INT 从-231到-231-1的整型数据,存储大小2个字节 SMALLLINT 从-32768到32767的整数数据,存储大小4个字节 TINYINT 0~255的整数类型,存储大小1个 ...

  3. AC日记——二叉树最大宽度和高度 1501 codevs

    1501 二叉树最大宽度和高度  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver     题目描述 Description   给出一个二叉树,输出它的最大宽 ...

  4. Json 基于jQuery+JSON的省市联动效果

    helloweba.com 作者:月光光 时间:2012-09-12 21:57 标签: jQuery  JSON  Ajax  省市联动     省市区联动下拉效果在WEB中应用非常广泛,尤其在一些 ...

  5. 学习CSS的瓶颈

    何为学习瓶颈 学习到了一定的阶段,就很难继续提高水平的一种现象 这是很多人都正面对的,但同时自己并未意识到. 既然是瓶颈,那么一旦突破了,就是广阔天空! 你是否经常面对这样的情景: 遇到一个奇葩问题, ...

  6. 几种.NET平台数据持久化框架介绍

    原文连接:http://yuxnet.blog.163.com/blog/static/164863495201131532223362/ 在.NET平台下,关于数据持久层框架非常多,本文主要对如下几 ...

  7. java多线程系类:基础篇:01基本概念:

    这个系类的内容全部来源于http://www.cnblogs.com/skywang12345/p/3479024.html.特别在此声明!!! 本来想直接看那位作家的博客的,但还是复制过来. 多线程 ...

  8. 重构Web Api程序(Api Controller和Entity) 续篇(2)

    一代好的程序,是几经修改与重构出来的.有关此篇Insus.NET对前面所在修改与重构,还是没有觉得很完美简洁.特别对是存在的json文件进行修改或是删除时,我们原先是从文件读取数据,修改或是删除数据, ...

  9. 浅谈设计模式--建造器模式(Builder Pattern)

    建造器模式,是于创建带有大量参数的对象,并避免因参数数量多而产生的一些问题(如状态不一致-JavaBean的setter模式). 如果参数多且有些是必须初始化的,有些是不一定需要初始化的时候,创建对象 ...

  10. Jenkins进阶系列之——18Jenkins语言本地化

    在Jenkins中,英语一大片,看着各种蛋疼.非常高兴的是,Jenkins作为一个主流流行的持续构建工具,提供了一个本地化语言的配置界面. 你可以找到它,在Jenkins每页的左下角.如下图: 点击帮 ...