解题关键:带插入kdtree模板题。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define N 1000005
  6. #define inf (1<<30)
  7. using namespace std;
  8. int n,m,dim,rt,ans;
  9. struct node{int p[],x[],y[];}a[N];
  10. bool cmp(node x,node y){ return x.p[dim]<y.p[dim]; }
  11. struct kd_tree{
  12. int c[N][];
  13. node s[N],q;
  14. void update(int k){//管辖范围
  15. int l=c[k][],r=c[k][];
  16. for(int i=;i<;i++){
  17. if(l){ s[k].x[i]=min(s[k].x[i],s[l].x[i]); s[k].y[i]=max(s[k].y[i],s[l].y[i]); }
  18. if(r){ s[k].x[i]=min(s[k].x[i],s[r].x[i]); s[k].y[i]=max(s[k].y[i],s[r].y[i]); }
  19. }
  20. }
  21. void add(int k,node t){ for(int i=;i<;i++)s[k].x[i]=s[k].y[i]=s[k].p[i]=t.p[i]; }
  22. int dist(node t,int k){
  23. int tmp=;
  24. for(int i=;i<;i++) tmp+=max(,s[k].x[i]-t.p[i]);
  25. for(int i=;i<;i++) tmp+=max(,t.p[i]-s[k].y[i]);
  26. return tmp;
  27. }//?
  28. void build(int &k,int l,int r,int now){
  29. k=(l+r)>>; dim=now;
  30. nth_element(a+l,a+k,a+r+,cmp);
  31. add(k,a[k]);
  32. if(l<k) build(c[k][],l,k-,now^);
  33. if(k<r) build(c[k][],k+,r,now^);
  34. update(k);
  35. }
  36.  
  37. void ins(int k,int now){
  38. if(q.p[now]<s[k].p[now]){
  39. if(c[k][]) ins(c[k][],now^);
  40. else c[k][]=++n,add(n,q);
  41. }
  42. else{
  43. if(c[k][]) ins(c[k][],now^);
  44. else c[k][]=++n,add(n,q);
  45. }
  46. update(k);
  47. }
  48. void qry(int k){//曼哈顿距离,且只求最短,dis是最短距离
  49. int tmp=;
  50. for(int i=;i<;i++) tmp+=abs(s[k].p[i]-q.p[i]);
  51. ans=min(ans,tmp);
  52. int dl=c[k][]?dist(q,c[k][]):inf,dr=c[k][]?dist(q,c[k][]):inf;
  53. if(dl<dr){
  54. if(dl<ans) qry(c[k][]);
  55. if(dr<ans) qry(c[k][]);
  56. }else{
  57. if(dr<ans) qry(c[k][]);
  58. if(dl<ans) qry(c[k][]);
  59. }
  60. }
  61. }kd;
  62.  
  63. int main(){
  64. scanf("%d%d",&n,&m);
  65. for(int i=;i<=n;i++) scanf("%d%d",&a[i].p[],&a[i].p[]);
  66. kd.build(rt,,n,);
  67. while(m--){
  68. int k;
  69. scanf("%d%d%d",&k,&kd.q.p[],&kd.q.p[]);
  70. if(k==) kd.ins(rt,);
  71. else{
  72. ans=inf; kd.qry(rt); printf("%d\n",ans);
  73. }
  74. }
  75. return ;
  76. }

2、将2维普遍化。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define N 1000005
  6. #define inf (1<<30)
  7. using namespace std;
  8. int n,m,dim,rt,ans,k;
  9. struct node{int p[],minn[],maxx[];}a[N];
  10. bool cmp(node x,node y){ return x.p[dim]<y.p[dim]; }
  11. struct kd_tree{
  12. int c[N][];
  13. node s[N],q;
  14. void update(int o){//管辖范围
  15. int l=c[o][],r=c[o][];
  16. for(int i=;i<k;i++){
  17. if(l){ s[o].minn[i]=min(s[o].minn[i],s[l].minn[i]); s[o].maxx[i]=max(s[o].maxx[i],s[l].maxx[i]); }
  18. if(r){ s[o].minn[i]=min(s[o].minn[i],s[r].minn[i]); s[o].maxx[i]=max(s[o].maxx[i],s[r].maxx[i]); }
  19. }
  20. }
  21. void add(int o,node t){ for(int i=;i<k;i++)s[o].minn[i]=s[o].maxx[i]=s[o].p[i]=t.p[i]; }
  22. int dist(node t,int o){
  23. int tmp=;
  24. for(int i=;i<k;i++) tmp+=max(,s[o].minn[i]-t.p[i]);
  25. for(int i=;i<k;i++) tmp+=max(,t.p[i]-s[o].maxx[i]);
  26. return tmp;
  27. }//?
  28. void build(int &o,int l,int r,int now){
  29. o=(l+r)>>; dim=now%k;
  30. nth_element(a+l,a+o,a+r+,cmp);
  31. add(o,a[o]);
  32. if(l<o) build(c[o][],l,o-,now+);
  33. if(o<r) build(c[o][],o+,r,now+);
  34. update(o);
  35. }
  36.  
  37. void ins(int o,int now){
  38. now%=k;
  39. if(q.p[now]<s[o].p[now]){
  40. if(c[o][]) ins(c[o][],now+);
  41. else c[o][]=++n,add(n,q);
  42. }
  43. else{
  44. if(c[o][]) ins(c[o][],now+);
  45. else c[o][]=++n,add(n,q);
  46. }
  47. update(o);
  48. }
  49. void qry(int o){//曼哈顿距离,且只求最短,dis是最短距离
  50. int tmp=;
  51. for(int i=;i<k;i++) tmp+=abs(s[o].p[i]-q.p[i]);
  52. ans=min(ans,tmp);
  53. int dl=c[o][]?dist(q,c[o][]):inf,dr=c[o][]?dist(q,c[o][]):inf;
  54. if(dl<dr){
  55. if(dl<ans) qry(c[o][]);
  56. if(dr<ans) qry(c[o][]);
  57. }else{
  58. if(dr<ans) qry(c[o][]);
  59. if(dl<ans) qry(c[o][]);
  60. }
  61. }
  62. }kd;
  63.  
  64. int main(){
  65. k=;
  66. scanf("%d%d",&n,&m);
  67. for(int i=;i<=n;i++) scanf("%d%d",&a[i].p[],&a[i].p[]);
  68. kd.build(rt,,n,);
  69. while(m--){
  70. int k;
  71. scanf("%d%d%d",&k,&kd.q.p[],&kd.q.p[]);
  72. if(k==) kd.ins(rt,);
  73. else{
  74. ans=inf; kd.qry(rt); printf("%d\n",ans);
  75. }
  76. }
  77. return ;
  78. }

[bzoj2648]SJY摆棋子(带插入kd-tree)的更多相关文章

  1. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  2. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  3. [BZOJ2648] SJY摆棋子 kd-tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 5421  Solved: 1910[Submit][Status][Disc ...

  4. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

  5. Bzoj2648 SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 3128  Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...

  6. 2019.01.14 bzoj2648: SJY摆棋子(kd-tree)

    传送门 kd−treekd-treekd−tree模板题. 题意简述:支持在平面上插入一个点,求对于一个点的最近点对. 思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息 所以我用了 ...

  7. BZOJ2648 SJY摆棋子(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  8. 【kd-tree】bzoj2648 SJY摆棋子

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  9. KDTree(Bzoj2648: SJY摆棋子)

    题面 传送门 KDTree 大概就是一个分割\(k\)维空间的数据结构,二叉树 建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下 维护:维 ...

随机推荐

  1. FastAdmin 的 API 可以分级吗?

    FastAdmin 的 API 可以分级吗? 有小伙伴问 FastAdmin 的API 可以分别吗,使用 / 出现错误. Karson 的说明是: 完全支持的,默认是使用.进行分隔的,如果需要/,请开 ...

  2. VirtulBox安装虚拟机(鼠标点击时)0x00000000指令引用的0x00000000内存该内存不能为written错误解决方案

    这个错误并不是所有人都会用到,我用的是WIN7系统,公司的电脑.查找了很多原因后,发现的确是由于系统主题被破解过的原因. 手工恢复风险太高.通过下面的工具就可以直接恢复.UniversalThemeP ...

  3. PyBrain库的example之NFQ流程图分析

    PyBrain库的example之NFQ流程图分析 如下是测试程序.主要分析doEpisode和learn两个函数. #!/usr/bin/env python __author__ = 'Thoma ...

  4. RESTful的一个样例

    后台代码: @RequestMapping(value = { "queues" }) @ResponseBody public List<ResourcePool> ...

  5. jdk1.8新特性之方法引用

    方法引用其实就是方法调用,符号是两个冒号::来表示,左边是对象或类,右边是方法.它其实就是lambda表达式的进一步简化.如果不使用lambda表达式,那么也就没必要用方法引用了.啥是lambda,参 ...

  6. (转)Inno Setup入门(一)——最简单的安装脚本

    本文转载自:http://blog.csdn.net/Augusdi/article/details/8564788 一个最简单的安装脚本: 1.最简单的安装文件脚本: [setup] AppName ...

  7. Java 中的instanceof 运算符

    Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法:resu ...

  8. HDU2546题解

    解题思路:先对价格排序(顺序或倒序都可以),然后,对前n-1(从1开始.排序方式为顺序)做容量为m(卡上余额)-5的01背包(背包体积和价值相等).假设dp[i][j]表示从前i个背包中挑选体积不超过 ...

  9. 用户的 添加 权限 MySql远程登录

    添加一个用户 '; 为这个叫mongo的用户赋予操作z_0811数据库的所有权限 '; mysql如何修改开启允许远程连接   关于mysql远程连接的问题,大家在公司工作中,经常会遇到mysql数据 ...

  10. sql sever数据库常用的执行语句

    --使用master数据库use master --创建数据库文件create database 数据库名字 on( name=, --逻辑名称 filename= .ndf, --数据文件物理路径名 ...