题目背景

感谢@浮尘ii 提供的一组hack数据

题目描述

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

我们把 Ayu 生活的小镇看作一个二维平面坐标系,而 Ayu 会不定时地记起可能在某个点 (xmy) 埋下了天使玩偶;或者 Ayu 会询问你,假如她在 (x,y) ,那么她离近的天使玩偶可能埋下的地方有多远。

因为 Ayu 只会沿着平行坐标轴的方向来行动,所以在这个问题里我们定义两个点之间的距离为dist(A,B)=|Ax-Bx|+|Ay-By|。其中 Ax 表示点 A的横坐标,其余类似。

输入输出格式

输入格式:

第一行包含两个整数n和m ,在刚开始时,Ayu 已经知道有n个点可能埋着天使玩偶, 接下来 Ayu 要进行m 次操作

接下来n行,每行两个非负整数 (xi,yi),表示初始n个点的坐标。

再接下来m 行,每行三个非负整数 t,xi,yi。

如果t=1 ,则表示 Ayu 又回忆起了一个可能埋着玩偶的点 (xi,yi) 。

如果t=2 ,则表示 Ayu 询问如果她在点 (xi,yi) ,那么在已经回忆出来的点里,离她近的那个点有多远

输出格式:

对于每个t=2 的询问,在单独的一行内输出该询问的结果。

输入输出样例

输入样例#1:

  1. 2 3
  2. 1 1
  3. 2 3
  4. 2 1 2
  5. 1 3 3
  6. 2 4 2
输出样例#1:

  1. 1
  2. 2

说明

n,m<=300 000

xi,yi<=1 000 000

Solution:
  本题巨说是点分治裸题。。。然而我用$kd-tree$水了波$90$。(应该是可以$A$的,但是暂时不会玄学转树,留坑待填~)

  有必要先解释一下变量含义:$(d[0],d[1])$为当前根节点的坐标,$(mn[0],mn[1])$表示当前节点代表的二维平面中最左下角的坐标,$(mx[0],mx[1])$表示最右上角的坐标,$l,r$分别表示当前节点的左、右儿子。

  思路比较简单,构建二维搜索树,将每个点拍到面上去,从根节点往下每层交替按$x$和$y$为关键字建树。

  建树过程,要尽可能使得树保持平衡,所以每次以区间中间为当前根节点建树,二维平面分为左部和右部两部分,分别表示当前节点的左儿子和右儿子。

代码:

  1. #include<bits/stdc++.h>
  2. #define il inline
  3. #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
  4. #define Min(a,b) ((a)>(b)?(b):(a))
  5. #define Max(a,b) ((a)>(b)?(a):(b))
  6. using namespace std;
  7. const int N=,inf=;
  8. int n,m,x,y,opt,ans,cmpd,root;
  9. struct node{
  10. int d[],l,r,mn[],mx[];
  11. bool operator <(const node a){
  12. return ((d[cmpd]<a.d[cmpd])||(d[cmpd]==a.d[cmpd]&&d[!cmpd]<a.d[!cmpd]));
  13. }
  14. }t[N];
  15.  
  16. il int gi(){
  17. int a=;char x=getchar();bool f=;
  18. while((x<''||x>'')&&x!='-')x=getchar();
  19. if(x=='-')x=getchar(),f=;
  20. while(x>=''&&x<='')a=(a<<)+(a<<)+x-,x=getchar();
  21. return f?-a:a;
  22. }
  23.  
  24. il void update(int rt){
  25. int ls=t[rt].l,rs=t[rt].r;
  26. if(ls){
  27. t[rt].mn[]=Min(t[rt].mn[],t[ls].mn[]);
  28. t[rt].mn[]=Min(t[rt].mn[],t[ls].mn[]);
  29. t[rt].mx[]=Max(t[rt].mx[],t[ls].mx[]);
  30. t[rt].mx[]=Max(t[rt].mx[],t[ls].mx[]);
  31. }
  32. if(rs){
  33. t[rt].mn[]=Min(t[rt].mn[],t[rs].mn[]);
  34. t[rt].mn[]=Min(t[rt].mn[],t[rs].mn[]);
  35. t[rt].mx[]=Max(t[rt].mx[],t[rs].mx[]);
  36. t[rt].mx[]=Max(t[rt].mx[],t[rs].mx[]);
  37. }
  38. }
  39.  
  40. il int build(int l,int r,int tw){
  41. cmpd=tw;
  42. int mid=l+r>>;
  43. nth_element(t+l+,t+mid+,t+r+);
  44. t[mid].mn[]=t[mid].mx[]=t[mid].d[];
  45. t[mid].mn[]=t[mid].mx[]=t[mid].d[];
  46. if(l!=mid)t[mid].l=build(l,mid-,!tw);
  47. if(r!=mid)t[mid].r=build(mid+,r,!tw);
  48. update(mid);
  49. return mid;
  50. }
  51.  
  52. il void insert(int rt){
  53. int op=,p=root;
  54. while(){
  55. if(t[rt].mn[]<t[p].mn[])t[p].mn[]=t[rt].mn[];
  56. if(t[rt].mn[]<t[p].mn[])t[p].mn[]=t[rt].mn[];
  57. if(t[rt].mx[]>t[p].mx[])t[p].mx[]=t[rt].mx[];
  58. if(t[rt].mx[]>t[p].mx[])t[p].mx[]=t[rt].mx[];
  59. if(t[rt].d[op]>=t[p].d[op]){
  60. if(!t[p].r){t[p].r=rt;return;}
  61. else p=t[p].r;
  62. }
  63. else {
  64. if(!t[p].l){t[p].l=rt;return;}
  65. else p=t[p].l;
  66. }
  67. op=!op;
  68. }
  69. }
  70.  
  71. il int mhd(int rt,int x,int y){
  72. int s=;
  73. if(x<t[rt].mn[])s+=(t[rt].mn[]-x);
  74. if(x>t[rt].mx[])s+=(x-t[rt].mx[]);
  75. if(y<t[rt].mn[])s+=(t[rt].mn[]-y);
  76. if(y>t[rt].mx[])s+=(y-t[rt].mx[]);
  77. return s;
  78. }
  79.  
  80. il void query(int rt){
  81. int d0,dl,dr;
  82. d0=abs(t[rt].d[]-x)+abs(t[rt].d[]-y);
  83. if(d0<ans)ans=d0;
  84. if(t[rt].l)dl=mhd(t[rt].l,x,y);
  85. else dl=inf;
  86. if(t[rt].r)dr=mhd(t[rt].r,x,y);
  87. else dr=inf;
  88. if(dl<dr){
  89. if(dl<ans)query(t[rt].l);
  90. if(dr<ans)query(t[rt].r);
  91. }
  92. else {
  93. if(dr<ans)query(t[rt].r);
  94. if(dl<ans)query(t[rt].l);
  95. }
  96. }
  97.  
  98. int main(){
  99. n=gi(),m=gi();
  100. For(i,,n) t[i].d[]=gi(),t[i].d[]=gi();
  101. root=build(,n,);
  102. while(m--){
  103. opt=gi(),x=gi(),y=gi();
  104. if(opt==){
  105. n++;
  106. t[n].mn[]=t[n].mx[]=t[n].d[]=x;
  107. t[n].mn[]=t[n].mx[]=t[n].d[]=y;
  108. insert(n);
  109. }
  110. else {
  111. ans=inf;
  112. query(root);
  113. printf("%d\n",ans);
  114. }
  115. }
  116. return ;
  117. }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. centos安装smokeping

    本文摘自网友博客,并亲自验证 博客地址:https://blog.csdn.net/erica_yue/article/details/78455101 1.安装依赖包: yum install -y ...

  2. underscore.js 分析 第三天

    // Create a safe reference to the Underscore object for use below. // 为Underscore对象创建一个安全的引用 // _为一个 ...

  3. 探寻ASP.NET MVC鲜为人知的奥秘(3):寻找多语言的最佳实践方式

    如果你的网站需要被世界各地的人访问,访问者会使用各种不同的语言和文字书写习惯,那么创建一个支持多语言的网站就是十分必要的了,这一篇文章就讲述怎么快速合理的创建网站对多语言的支持.接下来通过一个实例来讲 ...

  4. Python接口测试实战1(下)- 接口测试工具的使用

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  5. ddms+adt+jdk的安装及调试开发安卓

    _______ ddms+adt+jdk的安装及调试开发安卓 目录 阐述 1 1  jdk安装 1 2  sdk安装 3 3  Eclipse安装 6 4  ADT安装 10 5  Ddms使用 16 ...

  6. 【转】微信小程序实现自动化测试

    山雨欲来风满楼,最近微信小程序相关开发文章吹遍大江南北,亦有摧枯拉朽万象更新之势.问小程序形为何物,直教IT众生怡情悦性高潮迭起.作为一名有着远大理想“包袱”与互联网变革 “使命感”的测试工程师,我再 ...

  7. 自动化运维工具saltstack03 -- 之SaltStack的数据系统

    SaltStack数据系统 saltstack有两种数据系统:grains与pillar 1.SaltStack数据系统之grains grains可以收集minion端的静态数据(即机器启动时收集一 ...

  8. docker简单使用+django+uwsgi+nginx项目部署

    使用docker 搭建 centos7 环境: 主机环境:windows 10专业版 一.安装docker Hub.docker.com官网下载 docker for windows 安装完成后,任务 ...

  9. Python 3 利用 Dlib 实现摄像头人脸检测特征点标定

    0. 引言 利用 Python 开发,借助 Dlib 库捕获摄像头中的人脸,进行实时人脸 68 个特征点标定: 支持多张人脸: 有截图功能: 图 1 工程效果示例( gif ) 图 2 工程效果示例( ...

  10. Keepalived两节点出现双VIP的情况

    一.现象 安装有keepalived的两节点服务器10.11.4.186/187,主要做高可用,设定VIP10.11.4.185. 首先启动10.11.4.186的keepalived服务,服务启动正 ...