2648: SJY摆棋子

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2968  Solved: 1011
[Submit][Status][Discuss]

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可以过

Source

[Submit][Status][Discuss]

既然题目都这么友好地告诉我们KD-Tree可解了,那就没理由不写KD-Tree了,对吧。( ̄_, ̄ )

对于原本就存在的黑色棋子,那么就先读入,然后用build()建树;对于之后插入的黑色棋子,在insert()中根据KD-Tree的二叉树性质找到合适的叶子结点,插入即可。查询的时候,记得用最优性剪枝,并且合理利用估价函数,以避免TLE。

  1. #include <bits/stdc++.h>
  2.  
  3. inline int next(void) {
  4. int ret = , neg = , bit = getchar();
  5. while (bit < '') {
  6. if (bit == '-')
  7. neg ^= true;
  8. bit = getchar();
  9. }
  10. while (bit >= '') {
  11. ret = ret* + bit - '';
  12. bit = getchar();
  13. }
  14. return neg ? -ret : ret;
  15. }
  16.  
  17. const int siz = 2e6 + ;
  18. const int inf = 2e9 + ;
  19.  
  20. struct node {
  21. int pos[];
  22. int son[];
  23. int min[];
  24. int max[];
  25. }tree[siz];
  26.  
  27. int root;
  28. int cmp_k;
  29. int qry_x;
  30. int qry_y;
  31. int answer;
  32.  
  33. inline bool cmp(node a, node b) {
  34. return
  35. (a.pos[cmp_k] ^ b.pos[cmp_k])
  36. ? (a.pos[cmp_k] < b.pos[cmp_k])
  37. : (a.pos[!cmp_k] < b.pos[!cmp_k]);
  38. }
  39.  
  40. inline void update(int t) {
  41. for (int i = ; i < ; ++i)if (tree[t].son[i])
  42. for (int j = ; j < ; ++j) {
  43. if (tree[t].min[j] > tree[tree[t].son[i]].min[j])
  44. tree[t].min[j] = tree[tree[t].son[i]].min[j];
  45. if (tree[t].max[j] < tree[tree[t].son[i]].max[j])
  46. tree[t].max[j] = tree[tree[t].son[i]].max[j];
  47. }
  48. }
  49.  
  50. int build(int l, int r, int k) {
  51. int d = (l + r) >> ; cmp_k = k;
  52. std::nth_element(
  53. tree + l + ,
  54. tree + d + ,
  55. tree + r + ,
  56. cmp);
  57. if (l != d)tree[d].son[] = build(l, d - , !k);
  58. if (r != d)tree[d].son[] = build(d + , r, !k);
  59. tree[d].min[] = tree[d].max[] = tree[d].pos[];
  60. tree[d].min[] = tree[d].max[] = tree[d].pos[];
  61. return update(d), d;
  62. }
  63.  
  64. inline void insert(int t) {
  65. for (int p = root, k = ; p != t; k = !k) {
  66. for (int i = ; i < ; ++i) {
  67. if (tree[p].min[i] > tree[t].min[i])
  68. tree[p].min[i] = tree[t].min[i];
  69. if (tree[p].max[i] < tree[t].max[i])
  70. tree[p].max[i] = tree[t].max[i];
  71. }
  72. int &to = tree[p].son[tree[t].pos[k] >= tree[p].pos[k]];
  73. to = to ? to : t; p = to;
  74. }
  75. }
  76.  
  77. inline int dist(int t) {
  78. if (!t)return inf;
  79. int ret = ;
  80. if (qry_x < tree[t].min[])
  81. ret += tree[t].min[] - qry_x;
  82. if (qry_x > tree[t].max[])
  83. ret += qry_x - tree[t].max[];
  84. if (qry_y < tree[t].min[])
  85. ret += tree[t].min[] - qry_y;
  86. if (qry_y > tree[t].max[])
  87. ret += qry_y - tree[t].max[];
  88. return ret;
  89. }
  90.  
  91. void query(int t) {
  92. answer = std::min(answer,
  93. std::abs(tree[t].pos[] - qry_x)
  94. + std::abs(tree[t].pos[] - qry_y));
  95. if (dist(tree[t].son[]) < dist(tree[t].son[])) {
  96. if (dist(tree[t].son[]) < answer)query(tree[t].son[]);
  97. if (dist(tree[t].son[]) < answer)query(tree[t].son[]);
  98. } else {
  99. if (dist(tree[t].son[]) < answer)query(tree[t].son[]);
  100. if (dist(tree[t].son[]) < answer)query(tree[t].son[]);
  101. }
  102. }
  103.  
  104. signed main(void) {
  105. int n = next();
  106. int m = next();
  107. for (int i = ; i <= n; ++i) {
  108. tree[i].pos[] = next();
  109. tree[i].pos[] = next();
  110. }
  111. root = build(, n, );
  112. for (int i = ; i <= m; ++i) {
  113. int k = next();
  114. int x = next();
  115. int y = next();
  116. if (k == ) {
  117. ++n;
  118. tree[n].min[] = tree[n].max[] = tree[n].pos[] = x;
  119. tree[n].min[] = tree[n].max[] = tree[n].pos[] = y;
  120. insert(n);
  121. }
  122. else {
  123. qry_x = x;
  124. qry_y = y;
  125. answer = inf;
  126. query(root);
  127. printf("%d\n", answer);
  128. }
  129. }
  130. }

@Author: YouSiki

BZOJ 2648: SJY摆棋子的更多相关文章

  1. BZOJ 2648: SJY摆棋子 kdtree

    2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...

  2. bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree

    2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec  Memory Limit: 128 MB Description 这天,S ...

  3. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  4. bzoj 2648 SJY摆棋子 kd树

    题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...

  5. BZOJ 2648 SJY摆棋子(KD Tree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...

  6. bzoj 2648 SJY摆棋子——KDtree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 第一道KDtree! 学习资料:https://blog.csdn.net/zhl30 ...

  7. bzoj 2648 SJY摆棋子 —— K-D树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...

  8. BZOJ 2648 SJY摆棋子 ——KD-Tree

    [题目分析] KD-Tree第一题,其实大概就是搜索剪枝的思想,在随机数据下可以表现的非常好NlogN,但是特殊数据下会达到N^2. 精髓就在于估价函数get以及按照不同维度顺序划分的思想. [代码] ...

  9. BZOJ 2648 SJY摆棋子(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2716 [题目大意] 给出一些点,同时不断插入点和询问某点离插入点最近距离 [题解] 我 ...

随机推荐

  1. WIN7下强制分第四个主分区的方法

    通过磁盘管理的界面方式, 第四个分区会被分成扩展分区, 建议通过命令行 打开命令行运行diskpart, list disk 会列出所有磁盘, 选择要操作的磁盘序号如1,select disk 1 如 ...

  2. LeetCode 01 Two Sum swift

    class TwoSum { func sumTow(nums: [Int], target: Int)->[Int]{ ,]; ;x<nums.count;x++){ ;y<num ...

  3. Kibana+X-Pack

    Kibana+X-Pack介绍使用(全)   Kibana是一个为 ElasticSearch 提供的数据分析的 Web 接口.可使用它对日志进行高效的搜索.可视化.分析等各种操作.Kibana目前最 ...

  4. codevs2693 上学路线(施工)

    难度等级:黄金 2693 上学路线(施工) 题目描述 Description 问题描述 你所在的城市街道好像一个棋盘,有a条南北方向的街道和b条东西方向的街道. 南北方向a条街道从西到东依次编号为1到 ...

  5. 某站出品2016织梦CMS进阶教程共12课(附文档+工具)

    此为广告商内容使用最新版的dede cms建站 V5.7 sp1,经常注意后台的升级信息哦!一.安装DEDE的时候数据库的表前缀,最好改一下,不用dedecms默认的前缀dede_,随便一个名称即可. ...

  6. 异常和IO

    异常 异常是指java程序运行时(非编译)所发生的非正常情况或错误. Java对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为 java.lang.Throwable, ...

  7. opencv3-core之基本操作

    这一篇打算将core部分的例子说完,这都是基于<opencv2.4.9tutorial.pdf>中的core部分,其实这些例子后期都很稳定的,也就是说就算是2.3.1和2.4.10 ,这几 ...

  8. react的基本学习

    1.<SubSubComp {...this.props } /> 传递属性,{...props}的方式为组件传递了这两个属性,这就是JSX中的延展属性,"..."成为 ...

  9. 如何实现EndNote中的PDF批量导出

    如果在EndNote数据库中已建立大量的参考文献,且每条文献都有PDF文件对应,怎样将需要的某十几条甚至几十条参考文献对应的PDF文件从数据库导出另存在新建的文件夹   1. 按住“Ctrl”键,逐条 ...

  10. hihocoder1241 Best Route in a Grid

    题目链接:hihocoder 1241 题意: n*n的格阵,每个方格内有一个数字.蚂蚁从左上角走到右下角,数字是零的方格不能走,只能向右向下走.蚂蚁走的路径上全部方格的的乘积为s,要使s低位0的个数 ...