BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree

Description

这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

Input

第一行两个数 N M
以后M行,每行3个数 t x y
如果t=1 那么放下一个黑色棋子
如果t=2 那么放下一个白色棋子

Output

对于每个T=2 输出一个最小距离

Sample Input

2 3
1 1
2 3
2 1 2
1 3 3
2 4 2

Sample Output

1
2

HINT

kdtree可以过


kdtree是主要处理多维空间信息的工具。

当k=2时通常用来解决矩形查询问题,已知的一些矩形查询问题复杂度可以证明。

不过由于kdtree的实质看起来像剪枝,处理其他问题时也有很优越的时间。

kdtree像是一棵BST,它对于每层找到坐标为中位数的点当做这个点维护的信息,然后递归左右。

建树时通常横着切一刀竖着切一刀,再用nth_element来保证复杂度。

每个节点维护子树信息,mx[p][0]和mn[p][0]表示横坐标的范围,纵坐标同理。

通常插入点的时候要保证平衡而重构kdtree。

对于这道题我们维护出kdtree的信息。

查询时面对ls和rs两个矩形,分别求出他们的估价dis,即查询点到两个矩形的曼哈顿最小距离。

先递归dis小的那个,然后再判断答案和dis的关系决定是否递归另一棵子树。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. #define N 1000050
  6. #define ls ch[p][0]
  7. #define rs ch[p][1]
  8. #define _min(x,y) ((x)<(y)?(x):(y))
  9. #define _max(x,y) ((x)>(y)?(x):(y))
  10. int mx[N][2],mn[N][2],ch[N][2],now,root,ans,n,m,dep[N],maxdep;
  11. inline char nc() {
  12. static char buf[100000],*p1,*p2;
  13. return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
  14. }
  15. int rd() {
  16. int x=0; char s=nc();
  17. while(s<'0'||s>'9') s=nc();
  18. while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+s-'0',s=nc();
  19. return x;
  20. }
  21. char pbuf[100000],*pp=pbuf;
  22. void push(const char ch) {
  23. if(pp-pbuf==100000) fwrite(pbuf,1,100000,stdout),pp=pbuf;
  24. *pp++=ch;
  25. }
  26. void write(int x) {
  27. static char sta[35];
  28. int top=0;
  29. do{sta[++top]=x%10,x/=10;}while(x);
  30. while(top) push(sta[top--]+'0');
  31. push('\n');
  32. }
  33. struct Point {
  34. int p[2];
  35. bool operator < (const Point &u) const {
  36. return p[now]==u.p[now]?p[!now]<u.p[!now]:p[now]<u.p[now];
  37. }
  38. }a[N];
  39. int Abs(int x) {return x>0?x:-x;}
  40. void pushup(int p,int x) {
  41. mx[p][0]=_max(mx[p][0],mx[x][0]);
  42. mx[p][1]=_max(mx[p][1],mx[x][1]);
  43. mn[p][0]=_min(mn[p][0],mn[x][0]);
  44. mn[p][1]=_min(mn[p][1],mn[x][1]);
  45. }
  46. int build(int l,int r,int type,int fa) {
  47. int mid=(l+r)>>1;
  48. dep[mid]=dep[fa]+1;
  49. maxdep=_max(maxdep,dep[mid]);
  50. now=type;
  51. nth_element(a+l,a+mid,a+r+1);
  52. mx[mid][0]=mn[mid][0]=a[mid].p[0];
  53. mx[mid][1]=mn[mid][1]=a[mid].p[1];
  54. if(l<mid) ch[mid][0]=build(l,mid-1,!type,mid),pushup(mid,ch[mid][0]);
  55. if(r>mid) ch[mid][1]=build(mid+1,r,!type,mid),pushup(mid,ch[mid][1]);
  56. return mid;
  57. }
  58. void insert(int x) {
  59. int p=root;
  60. now=0;
  61. while(1) {
  62. pushup(p,x);
  63. if(a[x].p[now]<a[p].p[now]) {
  64. if(ls) p=ls;
  65. else {ls=x; pushup(p,x); dep[x]=dep[p]+1; break;}
  66. }else {
  67. if(rs) p=rs;
  68. else {rs=x; pushup(p,x); dep[x]=dep[p]+1; break;}
  69. }
  70. now=now^1;
  71. }
  72. maxdep=_max(maxdep,dep[x]);
  73. if(maxdep>100) maxdep=0,root=build(1,n,0,0);
  74. }
  75. int getdis(int x,int y,int p) {
  76. int re=0;
  77. if(x<mn[p][0]) re+=mn[p][0]-x;
  78. if(x>mx[p][0]) re+=x-mx[p][0];
  79. if(y<mn[p][1]) re+=mn[p][1]-y;
  80. if(y>mx[p][1]) re+=y-mx[p][1];
  81. return re;
  82. }
  83. void query(int x,int y,int p) {
  84. int re=Abs(x-a[p].p[0])+Abs(y-a[p].p[1]),dl,dr;
  85. if(re<ans) ans=re;
  86. dl=ls?getdis(x,y,ls):0x3f3f3f3f;
  87. dr=rs?getdis(x,y,rs):0x3f3f3f3f;
  88. if(dl<dr) {
  89. if(dl<ans) query(x,y,ls);
  90. if(dr<ans) query(x,y,rs);
  91. }else {
  92. if(dr<ans) query(x,y,rs);
  93. if(dl<ans) query(x,y,ls);
  94. }
  95. }
  96. int main() {
  97. n=rd(); m=rd();
  98. int i,opt,x,y;
  99. for(i=1;i<=n;i++) a[i].p[0]=rd(),a[i].p[1]=rd();
  100. root=build(1,n,0,0);
  101. while(m--) {
  102. opt=rd(); x=rd(); y=rd();
  103. if(opt==1) n++,a[n].p[0]=mx[n][0]=mn[n][0]=x,a[n].p[1]=mx[n][1]=mn[n][1]=y,insert(n);
  104. else ans=0x3f3f3f3f,query(x,y,root),write(ans);
  105. }
  106. fwrite(pbuf,1,pp-pbuf,stdout);
  107. }

BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree的更多相关文章

  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. 天使玩偶/SJY摆棋子

    P4169 [Violet]天使玩偶/SJY摆棋子 CDQ分治的题目. 我们发现题目要我们求的\(|A_x-B_x|+|A_y-B_y|\)的绝对值号比较恶心. 试想一下怎么去掉 如果所有的点都在我们 ...

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

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

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

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

随机推荐

  1. Java HashMap学习笔记

    1.HashMap数据结构 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外.HashMap实际 ...

  2. C# 线程中更新ListView某单元格导致闪烁问题的解决

    项目中需要用线程处理一些事务.处理结果(已经处理的比例)随时显示在ListView的某区域. 由于线程循环动作较快,导致被更新的单元格甚至所在行都有闪烁现象. 后来考虑到线程算的值整数部分未必变化很快 ...

  3. NYOJ 353 3D dungeon 【bfs】

    题意:给你一个高L长R宽C的图形.每个坐标都能够视为一个方格.你一次能够向上.下.左,右,前,后任一方向移动一个方格, 可是不能向有#标记的方格移动. 问:从S出发能不能到达E,假设能请输出最少的移动 ...

  4. python入门之搭建环境

    进入以下网站:python.org 选择你喜欢(需要)的版本下载 点击下载即可,本次提供下载:python3.6.3 (国外架设,非常慢) ,用百度的平台吧:python3.6.1,多谢百度. 开始安 ...

  5. PCB板布线中地线和电源线的布线规则

    电源. 地线的布置考虑不周到而引起干扰,使产品的性能下降,严重时会降低产品的成功率.要把电源线和地线处理好,将电源线和地线所产生的噪音干扰降到最低限度,以保证产品的质量.一.电源线和地线的布线规则1) ...

  6. ORACLE 查看表结构

    select table_name from user_tables; //当前用户的表 select table_name from all_tables; //所有用户的表 select tabl ...

  7. php返回HTTP状态码

    HTTP协议状态码,调用函数时候只需要将$num赋予一个下表中的已知值就直接会返回状态了.<?PHP /** * HTTP Protocol defined status codes* HTTP ...

  8. linux cat命令(转载)

    来源:http://blog.sina.com.cn/s/blog_52f6ead0010127xm.html 1.cat 显示文件连接文件内容的工具: cat 是一个文本文件查看和连接工具. 查看一 ...

  9. 目标检测之积分图---integral image 积分图2

    前面在图像处理一栏中涉及到boxfilter 的时候,简单介绍过积分图,就是每个像素点是左边和上边的累加和,这样的话可以方便均值和方差,以及直方图统计的相关运算,这里再次结合网络资源重新单独对积分图做 ...

  10. 在VS2015中增加JQuery引用及智能提示

      打开VS2015,从"工具"菜单选择NuGet选项,搜索Jquery,并点击安装.   可以看到解决方案的scripts增加了对应文件的引用   在HTML文件中可以直接引用j ...