题目

\(KD-tree\)做最近点对的复杂度好像是假的吧,怎么看也看不出来是\(O(\sqrt{n})\)啊

首先\(KD-tree\)长得和平衡树还是很像的,每个节点都存储了一个\(k\)维空间上的点

但是\(KD-tree\)的每一棵子树都是一个\(k\)维的空间,对于\(2D-tree\)来说就是一个矩形

我们存好这个矩形的内最小和最大的的\(x,y\)坐标,就可以利用这个东西来剪枝了

如果发现询问点和矩形的曼哈顿距离都超过了当前答案,我们就没有必要进入这个子树了

由于这道题还有插入,我们往某一个位置反复插入可能会导致树高过大,于是自闭

可以利用替罪羊的思想,对于一个点\(x\),发现\(max(sz[l[x]],sz[r[x]])>sz[x]\times \alpha\),就说明这个子树很不平衡了,我们就暴力重构一下,\(\alpha\)一般取\(0.65\)到\(0.75\)就好

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #define re register
  6. #define LL long long
  7. #define max(a,b) ((a)>(b)?(a):(b))
  8. #define min(a,b) ((a)<(b)?(a):(b))
  9. const int maxn=1000005;
  10. const int inf=99999999;
  11. const double alph=0.75;
  12. inline int read() {
  13. char c=getchar();int x=0;while(c<'0'||x>'9') c=getchar();
  14. while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
  15. }
  16. int n,m,cnt,op,ans,top;
  17. int mx[maxn][2],mi[maxn][2],sz[maxn],st[maxn];
  18. int l[maxn],r[maxn];
  19. struct Point{int x[2];}p[maxn],id[maxn];
  20. inline int newNode() {
  21. if(top) return st[top--];
  22. return ++cnt;
  23. }
  24. inline int cmp(Point A,Point B) {return A.x[op]<B.x[op];}
  25. inline void pushup(int k) {
  26. mi[k][0]=mx[k][0]=id[k].x[0];
  27. mi[k][1]=mx[k][1]=id[k].x[1];
  28. for(re int i=0;i<2;i++) {
  29. if(l[k]) mi[k][i]=min(mi[k][i],mi[l[k]][i]),
  30. mx[k][i]=max(mx[k][i],mx[l[k]][i]);
  31. if(r[k]) mi[k][i]=min(mi[k][i],mi[r[k]][i]);
  32. mx[k][i]=max(mx[k][i],mx[r[k]][i]);
  33. }
  34. sz[k]=sz[l[k]]+sz[r[k]]+1;
  35. }
  36. int build(int x,int y,int o) {
  37. if(x>y) return 0;
  38. int now=newNode();
  39. int mid=x+y>>1;
  40. op=o;std::nth_element(p+x,p+mid,p+y+1,cmp);id[now]=p[mid];
  41. l[now]=build(x,mid-1,o^1);r[now]=build(mid+1,y,o^1);
  42. pushup(now);return now;
  43. }
  44. inline int getdis(Point a,int k) {
  45. int res=0;
  46. for(re int i=0;i<2;i++) {
  47. if(a.x[i]>=mi[k][i]&&a.x[i]<=mx[k][i]) continue;
  48. if(a.x[i]<=mi[k][i]) res+=mi[k][i]-a.x[i];
  49. else if(a.x[i]>=mx[k][i]) res+=a.x[i]-mx[k][i];
  50. }
  51. return res;
  52. }
  53. inline int dis(Point a,Point b) {return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);}
  54. void query(Point now,int k) {
  55. ans=min(ans,dis(now,id[k]));
  56. int dl=inf,dr=inf;
  57. if(l[k]) dl=getdis(now,l[k]);
  58. if(r[k]) dr=getdis(now,r[k]);
  59. if(dl<dr) {
  60. if(dl<ans) query(now,l[k]);
  61. if(dr<ans) query(now,r[k]);
  62. }
  63. else {
  64. if(dr<ans) query(now,r[k]);
  65. if(dl<ans) query(now,l[k]);
  66. }
  67. }
  68. inline void del(int x) {
  69. if(l[x]) del(l[x]);
  70. st[++top]=x;p[++n]=id[x];
  71. if(r[x]) del(r[x]);
  72. }
  73. inline int check(int k,int o) {
  74. if(max(sz[l[k]],sz[r[k]])>sz[k]*alph) {
  75. n=0,del(k);
  76. return build(1,n,o);
  77. }
  78. return k;
  79. }
  80. int ins(int k,int now,int o) {
  81. if(!k) {
  82. k=newNode();
  83. id[k]=p[now];pushup(k);
  84. return k;
  85. }
  86. if(p[now].x[o]<=id[k].x[o]) l[k]=ins(l[k],now,o^1);
  87. else r[k]=ins(r[k],now,o^1);
  88. pushup(k);return check(k,o);
  89. }
  90. int main() {
  91. n=read(),m=read();
  92. for(re int i=1;i<=n;i++) p[i].x[0]=read(),p[i].x[1]=read();
  93. build(1,n,0);int opt,x,y;
  94. while(m--) {
  95. opt=read(),x=read(),y=read();
  96. if(opt==2) {
  97. ans=inf;Point now;
  98. now.x[0]=x,now.x[1]=y;
  99. query(now,1);
  100. printf("%d\n",ans);
  101. }
  102. if(opt==1) {
  103. p[++n].x[0]=x,p[n].x[1]=y;
  104. ins(1,n,0);
  105. }
  106. }
  107. return 0;
  108. }

[Violet]天使玩偶/SJY摆棋子的更多相关文章

  1. bzoj2716/2648 / P4169 [Violet]天使玩偶/SJY摆棋子

    P4169 [Violet]天使玩偶/SJY摆棋子 k-d tree 模板 找了好几天才发现输出优化错了....真是zz...... 当子树非常不平衡时,就用替罪羊树的思想,拍扁重建. luogu有个 ...

  2. 【LG4169】[Violet]天使玩偶/SJY摆棋子

    [LG4169][Violet]天使玩偶/SJY摆棋子 题面 洛谷 题解 至于\(cdq\)分治的解法,以前写过 \(kdTree\)的解法好像还\(sb\)一些 就是记一下子树的横.纵坐标最值然后求 ...

  3. 洛谷 P4169 [Violet]天使玩偶/SJY摆棋子 解题报告

    P4169 [Violet]天使玩偶/SJY摆棋子 题目描述 \(Ayu\)在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,\(Ayu\) 却忘了她把天使玩偶埋在了哪 ...

  4. luoguP4169 [Violet]天使玩偶/SJY摆棋子 K-Dtree

    P4169 [Violet]天使玩偶/SJY摆棋子 链接 luogu 思路 luogu以前用CDQ一直过不去. bzoj还是卡时过去的. 今天终于用k-dtree给过了. 代码 #include &l ...

  5. 洛谷P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治)

    [Violet]天使玩偶/SJY摆棋子 题目传送门 解题思路 用CDQ分治开了氧气跑过. 将输入给的顺序作为第一维的时间,x为第二维,y为第三维.对于距离一个询问(ax,ay),将询问分为四块,左上, ...

  6. [Violet]天使玩偶/SJY摆棋子 [cdq分治]

    P4169 [Violet]天使玩偶/SJY摆棋子 求离 \((x,y)\) 最近点的距离 距离的定义是 \(|x1-x2|+|y1-y2|\) 直接cdq 4次 考虑左上右上左下右下就可以了-略微卡 ...

  7. P4169 [Violet]天使玩偶/SJY摆棋子

    题目背景 感谢@浮尘ii 提供的一组hack数据 题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅 ...

  8. LG4169 [Violet]天使玩偶/SJY摆棋子

    题意 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 Ayu 生活的小镇 ...

  9. 洛谷P4169 [Violet]天使玩偶/SJY摆棋子

    %%%神仙\(SJY\) 题目大意: 一个二维平面,有两种操作: \(1.\)增加一个点\((x,y)\) \(2.\)询问距离\((x,y)\)曼哈顿最近的一个点有多远 \(n,m\le 300 0 ...

  10. Luogu P4169 [Violet]天使玩偶/SJY摆棋子

    传送门 二维平面修改+查询,cdq分治可以解决. 求关于某个点曼哈顿距离(x,y坐标)最近的点——dis(A,B) = |Ax-Bx|+|Ay-By| 但是如何去掉绝对值呢? 查看题解发现假设所有的点 ...

随机推荐

  1. 【转】maven profile实现多环境打包

    作为一名程序员,在开发的过程中,经常需要面对不同的运行环境(开发环境.测试环境.生产环境.内网环境.外网环境等等),在不同的环境中,相关的配置一般不一样,比如数据源配置.日志文件配置.以及一些软件运行 ...

  2. spring boot在intellij idea下整合mybatis可能遇到的问题

    org.apache.ibatis.builder.BuilderException: Wrong namespace. Expected 'com.sc.starry_sky.dao.UserMap ...

  3. Mysql explain分析sql语句执行效率

    mysql优化–explain分析sql语句执行效率 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 ...

  4. WebApiTestHelpPage

    这是个什么鬼,第一次见到的时候,我也不知道就花几天时间看了下它的代码 在网上搜索WebApiTestHelpPage会出来很多相关页面   但是它们都是介绍怎么用的,要么就是怎么添加注释   它是怎么 ...

  5. centos7下更新firefox

    下载最新版firefox 1.点击三条线-问号-firefox帮助-安装和更新-linux安装-系统和语言下载 保存到指定目录,比如home下 2.解压 tar xjf firefox-*.tar.b ...

  6. Vue如何使用动态刷新Echarts组件

    这次给大家带来Vue如何使用动态刷新Echarts组件,Vue使用动态刷新Echarts组件的注意事项有哪些,下面就是实战案例,一起来看一下. 需求背景:dashboard作为目前企业中后台产品的“门 ...

  7. js实现链式操作

    前言:前不久阿里远程面试时问了我一个问题,如下: function Person(){}; var person = new Person(); //实现person.set(10).get()返回2 ...

  8. [AngularJS] “路由”的定义概念、使用详解——AngularJS学习资料教程

    这是小编的一些学习资料,理论上只是为了自己以后学习需要的,但是还是需要认真对待的 以下内容仅供参考,请慎重使用学习 AngularJS“路由”的定义概念 AngularJS最近真的很火,很多同事啊同学 ...

  9. atitit.js 与c# java交互html5化的原理与总结.doc

    atitit.js 与c# java交互html5化的原理与总结.doc 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参数个数1 1.3. 事件监听2 2. sen ...

  10. Flutter 中 ListView 的使用

    这个小例子使用的是豆瓣 API 中 正在上映的电影的开放接口,要实现的主要效果如下: JSON 数据结构 Item 结构 Item 的结构是一个 Card 包含着一个 Row 然后这个 Row 里面左 ...