HDU 2966 KDtree模板
来源:互联网 发布:网民网络素养教育工作 编辑:程序博客网 时间:2024/05/27 19:25
题意:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2966
求每个点到最近邻点的距离平方
思路:
KDtree板子
代码:
// x维数为2的KDtree模板#include <bits/stdc++.h>using namespace std;typedef long long LL;const LL INF = 0x3f3f3f3f3f3f3f3f;const int MAXN = 1e5 + 10;struct Node { int lson, rson; LL Min[2], Max[2], x[2]; int id;} kdt[MAXN << 1], tmp;int root, cmp_x;LL ans, xx0, xx1;bool cmp (const Node &a, const Node &b) { return a.x[cmp_x] < b.x[cmp_x] || (a.x[cmp_x] == b.x[cmp_x] && a.x[cmp_x^1] < b.x[cmp_x^1]);}// 更新每个结点的边界信息void pushUp(int u, int v) { for (int i = 0; i < 2; i++) kdt[u].Min[i] = min(kdt[u].Min[i], kdt[v].Min[i]); for (int i = 0; i < 2; i++) kdt[u].Max[i] = max(kdt[u].Max[i], kdt[v].Max[i]);}int kdtBuild(int l, int r, int X) { int mid = (l + r) >> 1; kdt[mid].lson = kdt[mid].rson = 0; cmp_x = X; nth_element(kdt + l + 1, kdt + mid + 1, kdt + r + 1, cmp); // 将编号为mid的元素放在中间,比它小的放在前面,比它大的放后面 kdt[mid].Min[0] = kdt[mid].Max[0] = kdt[mid].x[0]; kdt[mid].Min[1] = kdt[mid].Max[1] = kdt[mid].x[1]; if (l != mid) kdt[mid].lson = kdtBuild(l, mid - 1, X ^ 1); if (r != mid) kdt[mid].rson = kdtBuild(mid + 1, r, X ^ 1); if (kdt[mid].lson) pushUp(mid, kdt[mid].lson); if (kdt[mid].rson) pushUp(mid, kdt[mid].rson); return mid;}// 插入新的结点void kdtInsert(int now) { int X = 0, p = root; while (true) { pushUp(p, now); if (kdt[now].x[X] < kdt[p].x[X]) { if (!kdt[p].lson) { kdt[p].lson = now; return; } else p = kdt[p].lson; } else { if (!kdt[p].rson) { kdt[p].rson = now; return; } else p = kdt[p].rson; } }}// 点(x,y)在结点id的边界范围内能得到的最大距离上界LL getMaxDis(int id, LL x0, LL x1) { LL res = 0; if (x0 < kdt[id].Min[0]) res += (kdt[id].Min[0] - x0) * (kdt[id].Min[0] - x0); if (x0 > kdt[id].Max[0]) res += (kdt[id].Max[0] - x0) * (kdt[id].Max[0] - x0); if (x1 < kdt[id].Min[1]) res += (kdt[id].Min[1] - x1) * (kdt[id].Min[1] - x1); if (x1 > kdt[id].Max[1]) res += (kdt[id].Max[1] - x1) * (kdt[id].Max[1] - x1); return res;}LL dist(int id, LL x0, LL x1) { return (kdt[id].x[0] - x0) * (kdt[id].x[0] - x0) + (kdt[id].x[1] - x1) * (kdt[id].x[1] - x1);}void kdtQuery(int p) { LL dl = INF, dr = INF, d; d = dist(p, xx0, xx1); if (kdt[p].x[0] == xx0 && kdt[p].x[1] == xx1) d = INF; // 查询(x,y)时要将(x,y)到自己的距离设为INF ans = min(ans, d); if (kdt[p].lson) dl = getMaxDis(kdt[p].lson, xx0, xx1); if (kdt[p].rson) dr = getMaxDis(kdt[p].rson, xx0, xx1); if (dl < dr) { if (dl < ans) kdtQuery(kdt[p].lson); if (dr < ans) kdtQuery(kdt[p].rson); } else { if (dr < ans) kdtQuery(kdt[p].rson); if (dl < ans) kdtQuery(kdt[p].lson); }}LL answer[MAXN];int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%I64d%I64d", &kdt[i].x[0], &kdt[i].x[1]); kdt[i].id = i; } root = kdtBuild(1, n, 0); for (int i = 1; i <= n; i++) { ans = INF; xx0 = kdt[i].x[0]; xx1 = kdt[i].x[1]; kdtQuery(root); answer[kdt[i].id] = ans; // printf("---%d\n", ans); } for (int i = 1; i <= n; i++) printf("%I64d\n", answer[i]); } return 0;}
阅读全文
0 0
- HDU 2966 KDtree模板
- bzoj2628 kdtree 模板
- hdu 4347 kdtree kdtree+优先队列
- HDU 4400-Mines-KDtree
- HDU 5992 (kdtree)
- HDU 4347 KNN+KDTree
- HDU 5126 stars KDTree
- HDU 5992 Finding Hotels KDtree
- HDU 5992 Finding Hotels KDtree
- kdtree
- kdTree
- KDtree
- bzoj 2648 (kdtree模板题)
- HDU 5809 Ants (KDtree+Tarjan)
- HDU 6183 Color it [KDtree+位压缩]
- 【BZOJ1941】【SDOI2010】Hide and Seek、KDTree【数组版】 模板、
- HDU 5140 Hun Gui Wei Company KDTree裸题
- HDU 2966 模板题
- Java并发容器之阻塞队列简介
- 前端js性能测试工具(JSLitmus)的使用
- LeetCode | 46. Permutations
- android 以太网和wifi共存
- 用DeviceIoControl获取系统磁盘信息
- HDU 2966 KDtree模板
- php 使用 domxpath读写元素
- Spark SQL之queryExecution运行流程解析Logical Plan(三)
- 小M开发_MySql零基础_day170628
- 数据结构和算法
- php_screw 源码加密
- 时间服务器客户端
- JAVA获取计算机的IP、名称、操作系统等信息
- mysql in 子条件中不支持limit