qwq(明明可以直接分治过掉的)

但是还是当作联系了

首先,对于这种点的题,很显然的套路,我们要维护一个子树\(mx[i],mn[i]\)分别表示每个维度的最大值和最小值

(这里有一个要注意的东西!就是我们\(up\)的时候,要判断一下当前是否还有左/右儿子)

  1. bool operator< (KD a,KD b)
  2. {
  3. return a.d[ymh]<b.d[ymh];
  4. }
  5. void up(int root)
  6. {
  7. for (int i=0;i<=1;i++)
  8. {
  9. if (t[root].l)
  10. {
  11. t[root].mn[i]=min(t[root].mn[i],t[t[root].l].mn[i]);
  12. t[root].mx[i]=max(t[root].mx[i],t[t[root].l].mx[i]);
  13. }
  14. if (t[root].r)
  15. {
  16. t[root].mn[i]=min(t[root].mn[i],t[t[root].r].mn[i]);
  17. t[root].mx[i]=max(t[root].mx[i],t[t[root].r].mx[i]);
  18. }
  19. }
  20. }
  21. void build(int &x,int l,int r,int dd)
  22. {
  23. ymh = dd;
  24. int mid = l+r >> 1;
  25. x = mid;
  26. nth_element(t+l,t+x,t+r+1);
  27. for (int i=0;i<=1;i++) t[x].mn[i]=t[x].mx[i]=t[x].d[i];
  28. if (l<x) build(t[x].l,l,mid-1,dd^1);
  29. if (x<r) build(t[x].r,mid+1,r,dd^1);
  30. up(x);
  31. }

其实这个题最重要的是估价函数该怎么写。

首先我们很容易发现,因为我们要求的是这个子树理论上到那个点的最短距离,所以我们需要这么考虑,如果当前点的坐标在\(mn到mx\)之间的话,那么理论上的最短距离就是0,否则就是当前这一维度距离\(mn和mx\)较近的距离

  1. double calc(KD a,KD b)
  2. {
  3. double tmp=0;
  4. for (int i=0;i<=1;i++)
  5. {
  6. if (b.d[i]<a.mn[i]) tmp=tmp+(a.mn[i]-b.d[i])*(a.mn[i]-b.d[i]);
  7. else if (b.d[i]>a.mx[i]) tmp=tmp+(a.mx[i]-b.d[i])*(a.mx[i]-b.d[i]);
  8. }
  9. return sqrt(tmp);
  10. }

其实剩下的就是和普通的kdtree差不多了

直接上就好了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<map>
  8. #include<set>
  9. #define mk makr_pair
  10. #define ll long long
  11. using namespace std;
  12. inline int read()
  13. {
  14. int x=0,f=1;char ch=getchar();
  15. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  16. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  17. return x*f;
  18. }
  19. const int maxn = 2e5+1e2;
  20. struct KD{
  21. double mx[4],mn[4],d[4];
  22. int l,r;
  23. };
  24. KD t[maxn],now;
  25. int n,m,root;
  26. int ymh;
  27. double ans;
  28. double tmp;
  29. int ii =0;
  30. bool operator< (KD a,KD b)
  31. {
  32. return a.d[ymh]<b.d[ymh];
  33. }
  34. void up(int root)
  35. {
  36. for (int i=0;i<=1;i++)
  37. {
  38. if (t[root].l)
  39. {
  40. t[root].mn[i]=min(t[root].mn[i],t[t[root].l].mn[i]);
  41. t[root].mx[i]=max(t[root].mx[i],t[t[root].l].mx[i]);
  42. }
  43. if (t[root].r)
  44. {
  45. t[root].mn[i]=min(t[root].mn[i],t[t[root].r].mn[i]);
  46. t[root].mx[i]=max(t[root].mx[i],t[t[root].r].mx[i]);
  47. }
  48. }
  49. }
  50. void build(int &x,int l,int r,int dd)
  51. {
  52. ymh = dd;
  53. int mid = l+r >> 1;
  54. x = mid;
  55. nth_element(t+l,t+x,t+r+1);
  56. for (int i=0;i<=1;i++) t[x].mn[i]=t[x].mx[i]=t[x].d[i];
  57. if (l<x) build(t[x].l,l,mid-1,dd^1);
  58. if (x<r) build(t[x].r,mid+1,r,dd^1);
  59. up(x);
  60. }
  61. double getdis(int a,KD b)
  62. {
  63. if (!a) return 0;
  64. double tmp=0;
  65. for (int i=0;i<=1;i++)
  66. {
  67. tmp=tmp+(t[a].d[i]-b.d[i])*(t[a].d[i]-b.d[i]);
  68. }
  69. return sqrt(tmp);
  70. }
  71. double calc(KD a,KD b)
  72. {
  73. double tmp=0;
  74. for (int i=0;i<=1;i++)
  75. {
  76. if (b.d[i]<a.mn[i]) tmp=tmp+(a.mn[i]-b.d[i])*(a.mn[i]-b.d[i]);
  77. else if (b.d[i]>a.mx[i]) tmp=tmp+(a.mx[i]-b.d[i])*(a.mx[i]-b.d[i]);
  78. }
  79. return sqrt(tmp);
  80. }
  81. void query(int x)
  82. {
  83. if (!x) return;
  84. double d1 = calc(t[t[x].l],now);
  85. double d2 = calc(t[t[x].r],now);
  86. double d = getdis(x,now);
  87. if (d<tmp && d!=0) tmp = d;
  88. if (d==0) ii++;
  89. if (d1<d2)
  90. {
  91. if (d1<tmp) query(t[x].l);
  92. if (d2<tmp) query(t[x].r);
  93. }
  94. else
  95. {
  96. if (d2<tmp) query(t[x].r);
  97. if (d1<tmp) query(t[x].l);
  98. }
  99. }
  100. int main()
  101. {
  102. n=read();
  103. for (int i=1;i<=n;i++)
  104. for (int j=0;j<=1;j++) t[i].d[j]=read();
  105. build(root,1,n,0);
  106. tmp = 1e18;
  107. for (int i=1;i<=n;i++)
  108. {
  109. ii=0;
  110. now = t[i];
  111. query(root);
  112. if (ii>1) tmp=0;
  113. }
  114. printf("%.4lf",tmp);
  115. return 0;
  116. }

洛谷1429 平面最近点对(KDTree)的更多相关文章

  1. (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714

    这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...

  2. 洛谷 P1429 平面最近点对(加强版) (分治模板题)

    题意:有\(n\)个点对,找到它们之间的最短距离. 题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若 ...

  3. Luogu 1429 平面最近点对 | 平面分治

    Luogu 1429 平面最近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 ...

  4. 洛谷P1257 平面上的最接近点对

    n<=10000个点,求欧几里德距离最小的一对点. 经典分治,把这些点按x排序,分成两半,每边分别算答案,答案是左边的最小,右边的最小,左右组起来的最小三者的最小.发现只有左右组的有点难写. 假 ...

  5. 洛谷 P6362 平面欧几里得最小生成树

    题目描述 平面上有 \(n\) 个点,第 \(i\) 个点坐标为 \((x_i, y_i)\).连接 \(i, j\) 两点的边权为 \(\sqrt{(x_i - x_j) ^ 2 + (y_i - ...

  6. 【洛谷P4148】简单题(kd-tree)

    传送门 题意: 给出一个\(n*n\)的棋盘,现在有两种操作:一种是某个格子里的数字加上\(A\),另一种是询问矩阵和. 空间限制:\(20MB\),强制在线. 思路: 直接\(kd-tree\)来搞 ...

  7. 洛谷 P1257 平面上的最接近点对 题解

    P1257 平面上的最接近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的. 输入格式 第一行:n:2≤n≤10000 接下来n行:每行两 ...

  8. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  9. 洛谷4631 [APIO2018] Circle selection 选圆圈 (KD树)

    qwq纪念AC450 一开始想这个题想复杂了. 首先,正解的做法是比较麻烦的. qwqq 那么就不如来一点暴力的东西,看到平面上点的距离的题,不难想到\(KD-Tree\) 我们用类似平面最近点对那个 ...

随机推荐

  1. 🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)

    RPC服务 什么叫RPC? RPC[Remote Procedure Call]是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范.它允许程序调用另一个地址空间(通常是共享网络的另 ...

  2. docker run命令指定GPU多个显卡不生效的问题解决和代码示例

    问题描述:我有一个程序(app),需要用到显卡来跑.原本的部署方式 是直接修改程序的配置文件来指定要用到的显卡. 这是我服务器的显卡信息:总共3卡 分别是 0卡 ,1卡和2卡. [root@k8s-r ...

  3. vue 前端反向代理后台,解决跨域问题

    // 和 src 同层的 config 文件夹下的 index.js dev 里面的 // Paths     assetsSubDirectory: 'static',     assetsPubl ...

  4. 简单C++线程池

    简单C++线程池 Java 中有一个很方便的 ThreadPoolExecutor,可以用做线程池.想找一下 C++ 的类似设施,尤其是能方便理解底层原理可上手的.网上找到的 demo,基本都是介绍的 ...

  5. 1,Spark参数调优

    Spark调优 目录 Spark调优 一.代码规范 1.1 避免创建重复RDD 1.2 尽量复用同一个RDD 1.3 多次使用的RDD要持久化 1.4 使用高性能算子 1.5 好习惯 二.参数调优 资 ...

  6. Identity角色管理一(准备工作)

    因角色管理需要有用户才能进行(需要将用户从角色中添加,删除)故角色管理代码依托用户管理 只需在Startup服务中添加角色管理即可完成 public void ConfigureServices(IS ...

  7. JAVA安全基础之代理模式(一)

    JAVA安全基础之代理模式(一) 代理模式是java的一种很常用的设计模式,理解代理模式,在我们进行java代码审计时候是非常有帮助的. 静态代理 代理,或者称为 Proxy ,简单理解就是事情我不用 ...

  8. 使用@EnableConfigurationProperties注册配置Bean时的命名规则

    Spring和Spring Boot开发中,常使用@ConfigurationProperties注解某个类,使其实例接受一组具有相同前缀的配置项. 可以使用@Component或Java Confi ...

  9. 测试开发【提测平台】分享10-Element UI抽屉和表单校验&增改接口合并实现应用管理

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 开篇说个小讨论,一个群里聊天聊到关于更新篇章的长度,是小篇幅多次,还是每次按照一个小完整的功能,我个人的是按照后种来的,主要的思考就是希望 ...

  10. PHP设计模式之状态模式

    状态模式从字面上其实并不是很好理解.这里的状态是什么意思呢?保存状态?那不就是备忘录模式了.其实,这里的状态是类的状态,通过改变类的某个状态,让这个类感觉像是换了一个类一样.说起来有点拗口吧,先学习概 ...