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可以过
【分析】
大家都知道kd_tree是什么吧,恩
就这样了..好吧,kd_tree一种空间树..看代码就知道了
  1. /*
  2. 唐代李白
  3. 《江夏别宋之悌》
  4. 楚水清若空,遥将碧海通。人分千里外,兴在一杯中。
  5. 谷鸟吟晴日,江猿啸晚风。平生不下泪,于此泣无穷.
  6. */
  7. #include <iostream>
  8. #include <cstdio>
  9. #include <algorithm>
  10. #include <cstring>
  11. #include <vector>
  12. #include <utility>
  13. #include <iomanip>
  14. #include <string>
  15. #include <cmath>
  16. #include <queue>
  17. #include <assert.h>
  18. #include <map>
  19. #include <ctime>
  20. #include <cstdlib>
  21. #include <stack>
  22. #include <set>
  23. #define LOCAL
  24. const int INF = 0x7fffffff;
  25. const int MAXN = + ;
  26. const int maxnode = * + * ;
  27. const int MAXM = + ;
  28. const int MAX = ;
  29. using namespace std;
  30. struct Node{//kd_tree
  31. int d[], l, r;
  32. int Max[], Min[];
  33. }t[ + ],tmp;
  34.  
  35. int n,m,root,cmp_d;
  36. int k1, k2, k3, Ans;
  37.  
  38. bool cmp(Node a, Node b){return (a.d[cmp_d]<b.d[cmp_d]) || ((a.d[cmp_d] == b.d[cmp_d]) && (a.d[!cmp_d] < b.d[!cmp_d]));}
  39. void update(int p){
  40. if (t[p].l){
  41. //左边最大的横坐标值
  42. t[p].Max[] = max(t[p].Max[], t[t[p].l].Max[]);
  43. t[p].Min[] = min(t[p].Min[], t[t[p].l].Min[]);
  44. t[p].Max[] = max(t[p].Max[], t[t[p].l].Max[]);
  45. t[p].Min[] = min(t[p].Min[], t[t[p].l].Min[]);
  46. }
  47. if (t[p].r){
  48. t[p].Max[] = max(t[p].Max[], t[t[p].r].Max[]);
  49. t[p].Min[] = min(t[p].Min[], t[t[p].r].Min[]);
  50. t[p].Max[] = max(t[p].Max[], t[t[p].r].Max[]);
  51. t[p].Min[] = min(t[p].Min[], t[t[p].r].Min[]);
  52. }
  53. return;
  54. }
  55. //d是横竖切..
  56. int build(int l, int r, int D){
  57. int mid = (l + r) / ;
  58. cmp_d = D;
  59. //按照cmp的比较顺序在l到r中找到第mid大的元素
  60. nth_element(t + l + , t + mid + , t + r + , cmp);
  61. t[mid].Max[] = t[mid].Min[] = t[mid].d[];
  62. t[mid].Max[] = t[mid].Min[] = t[mid].d[];
  63. //递归建树
  64. if (l != mid) t[mid].l = build(l, mid - , D ^ );
  65. if (r != mid) t[mid].r = build(mid + , r, D ^ );
  66. update(mid);
  67. return mid;
  68. }
  69. void insert(int now){
  70. int D = , p = root;//D还是表示方向
  71. while (){
  72. //边下传边更新
  73. t[p].Max[] = max(t[p].Max[], t[now].Max[]);
  74. t[p].Min[] = min(t[p].Min[], t[now].Min[]);
  75. t[p].Max[] = max(t[p].Max[], t[now].Max[]);
  76. t[p].Min[] = min(t[p].Min[], t[now].Min[]);
  77. //有没有点线段树的感觉..
  78. if (t[now].d[D] >= t[p].d[D]){
  79. if (t[p].r == ){
  80. t[p].r = now;
  81. return;
  82. }else p = t[p].r;
  83. }else{
  84. if (t[p].l == ){
  85. t[p].l = now;
  86. return;
  87. }else p = t[p].l;
  88. }
  89. D = D ^ ;
  90. }
  91. return;
  92. }
  93. int ABS(int x) {return x < ? -x : x;}
  94. //dist越小代表越趋近?
  95. int dist(int p1, int px, int py){
  96. int dist = ;
  97. if (px < t[p1].Min[]) dist += t[p1].Min[] - px;
  98. if (px > t[p1].Max[]) dist += px - t[p1].Max[];
  99. if (py < t[p1].Min[]) dist += t[p1].Min[] - py;
  100. if (py > t[p1].Max[]) dist += py - t[p1].Max[];
  101. return dist;
  102. }
  103. void ask(int p){
  104. int dl, dr, d0;
  105. //哈密顿距离
  106. d0=ABS(t[p].d[] - k2) + ABS(t[p].d[] - k3);
  107. if(d0 < Ans) Ans = d0;
  108. if(t[p].l) dl = dist(t[p].l, k2, k3); else dl = 0x7f7f7f7f;
  109. if(t[p].r) dr = dist(t[p].r, k2, k3); else dr = 0x7f7f7f7f;
  110. //应该是一个启发式的过程。
  111. if(dl < dr){
  112. if(dl < Ans) ask(t[p].l);
  113. if(dr < Ans) ask(t[p].r);
  114. }else{
  115. if(dr < Ans) ask(t[p].r);
  116. if(dl < Ans) ask(t[p].l);
  117. }
  118. }
  119.  
  120. void init(){
  121. //假设0为横坐标
  122. scanf("%d%d", &n, &m);
  123. for (int i = ; i <= n; i++)
  124. scanf("%d%d", &t[i].d[], &t[i].d[]);
  125. root = build(, n, );
  126. }
  127. void work(){
  128. for (int i = ; i <= m ;i++){
  129. scanf("%d%d%d", &k1, &k2, &k3);
  130. if (k1 == ){//黑棋
  131. ++n;
  132. t[n].Max[] = t[n].Min[] = t[n].d[] = k2;
  133. t[n].Max[] = t[n].Min[] = t[n].d[] = k3;
  134. insert(n);
  135. }else{
  136. Ans = 0x7f7f7f7f;
  137. ask(root);
  138. printf("%d\n", Ans);
  139. }
  140. }
  141. }
  142.  
  143. int main(){
  144.  
  145. init();
  146. work();
  147. return ;
  148. }
 

【BZOJ2648】【kd_tree】SJY摆棋子的更多相关文章

  1. 【BZOJ2648】SJY摆棋子(KD-Tree)

    [BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...

  2. 【BZOJ2648】SJY摆棋子 KDtree

    [BZOJ2648]SJY摆棋子 Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找 ...

  3. 【BZOJ2648】SJY摆棋子 [KD-tree]

    SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 这天,SJY显得无聊.在家自己 ...

  4. [bzoj2648/2716]SJY摆棋子_KD-Tree

    SJY摆旗子 bzoj-2648 题目大意:平面上有n个黑子.有m个操作,可以下一颗白子,查询与曼哈顿距离下最近黑子之间的曼哈顿距离,或者下一颗黑子. 注释:$1\le n,m\le 5\cdot 1 ...

  5. BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)

    Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子. ...

  6. 【bzoj2648】 SJY摆棋子

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 (题目链接) 题意 动态维护二维平面上的点的插入以及最邻近域搜索. Solution KDtr ...

  7. [bzoj2648/2716]SJY摆棋子

    平面上有n个点,要求支持插入一个点和查询一个点的最近点距离 n,m<=500000 用kdtree实现,但是复杂度貌似没法保证.....(莫名加了替罪羊重建更慢了...) #include< ...

  8. BZOJ2648:SJY摆棋子

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  9. 【BZOJ2648】SJY摆棋子

    题目大意:维护一个二维平面,平面上初始有 N 个点,支持两种操作:平面加点.查询距离某个指定点的最小哈密顿距离. 题解:学习到了 kd-tree 数据结构. kd-tree 类似于平衡树,即:每个节点 ...

  10. 【bzoj2648】SJY摆棋子(kdtree)

    传送门 题意: 二维平面上有若干个点. 现在要维护一种数据结构,支持插入一个点以及询问其余点到某个点的最小曼哈顿距离. 思路: 这是个\(kdtree\)模板题. \(kdtree\)是一种可以高效处 ...

随机推荐

  1. Windows Azure云服务价格调整通知

     好消息!由世纪互联运营的 Windows Azure推出优惠啦.我们采纳了多渠道客户的意见和建议,为了更好地服务大家,将降低多种云服务的价格,其中包括我们最受欢迎的服务 -虚拟机和 Block ...

  2. Linux Shell编程(30)——别名

    Bash别名本质上是一个简称, 缩写, 这可避免键入过长的命令序列. 例如,如果我们添加 alias lm="ls -l | more" 这一行到文件~/.bashrc file里 ...

  3. 【转】Adnroid4.0 签名混淆打包(conversion to dalvik format failed with error 1)

    原文网址:http://jojol-zhou.iteye.com/blog/1220541 自己的解决方法:关闭Eclipse,再开启Eclipse就可以. 最新Eclipse3.7+android ...

  4. Delphi实现WebService带身份认证的数据传输

    WebService使得不同开发工具开发出来的程序可以在网络连通的环境下相互通信,它最大的特点就是标准化(基于XML的一系列标准)带来的跨平台.跨开发工具的通用性,基于HTTP带来的畅通无阻的能力(跨 ...

  5. js弹框处理

    # -*- coding:utf-8 -*- """ js弹框处理 """ from selenium import webdriver d ...

  6. NIOS中双CPU系统的构建

    首先构建SOPC系统,先分别添加两个CPU,分别命名为CPU1和CPU2,设置如下图,其中CPU1运行VGA的乒乓游戏,CPU2运行音乐,这里为了简单,音乐用LED来表示. 这里CPU1选择是中等容量 ...

  7. 这几天阅读的shadowgun的几个shader

    直接从阅读时记录的笔记摘抄过来,写的比较随意. 1. MADFINGER-blinking-god-rays 除了可以用于实现太阳光线效果,还能调整参数让颜色随时间淡入淡出闪烁,能做出想灯光之类的效果 ...

  8. python 3 操作 excel

    看到一篇很好的python读写excel方式的对比文章: 用Python读写Excel文件 关于其他版本的excel,可以通过他提供的链接教程进行学习. XlsxWriter: https://git ...

  9. 关于fork有意思的两道题目

    http://www.spongeliu.com/123.html 第一题,计算下面代码理论上总共打印了多少行:(网易2011笔试题) #include #include #include int m ...

  10. Python异常处理 分类: python Raspberry Pi 服务器搭建 2015-04-01 13:22 172人阅读 评论(0) 收藏

    一个程序要保持稳定运行必须要有异常处理,本文将简单介绍Python中的try-except..异常处理语句的使用. 该种异常处理语法的规则是: 执行try下的语句,如果引发异常,则执行过程会跳到第一个 ...