题目描述

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

输入

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

输出

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

样例输入

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

样例输出

1
2


题解

KD-tree模板题

然后为了压行把insert写得比较难看

其实KD-tree这个东西和平衡树挺像的,差不多就是维护一个中序遍历,即左子树、根、右子树的某一关键字是递增的。

只不过这个关键字是不断变化的,即每一位轮流作为关键字排序(好像很高端的样子)。

所以这里使用algorithm中的STL函数:nth_element,它取出区间中指定排名的数放到指定位置,然后将小于或大于该数的放到指定位置的两端(注意一下开闭区间啥的)。

然后插入就像平衡树的插入,先找子树,直至找到空节点。

查询时采用一种启发式的思想,使用估价函数getdis,使得随机数据的时间大大减少。

然后这题好像不需要维护树不退化什么的,要维护的话直接重构即可。

#include <cstdio>
#include <algorithm>
#define N 1000010
#define inf 0x7fffffff
using namespace std;
struct data
{int p[2] , maxn[2] , minn[2] , c[2];
}a[N];
int root , d , ans;
bool cmp(data a , data b)
{return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d];
}
void pushup(int k , int s)
{a[k].maxn[0] = max(a[k].maxn[0] , a[s].maxn[0]);a[k].maxn[1] = max(a[k].maxn[1] , a[s].maxn[1]);a[k].minn[0] = min(a[k].minn[0] , a[s].minn[0]);a[k].minn[1] = min(a[k].minn[1] , a[s].minn[1]);
}
int build(int l , int r , int now)
{int mid = (l + r) >> 1;d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);a[mid].maxn[0] = a[mid].minn[0] = a[mid].p[0];a[mid].maxn[1] = a[mid].minn[1] = a[mid].p[1];if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);return mid;
}
void ins(int k)
{int *t = &root;d = 0;while(*t) pushup(*t , k) , t = &a[*t].c[a[k].p[d] > a[*t].p[d]] , d ^= 1;*t = k;
}
int getdis(int k , int x , int y)
{int ans = 0;if(x < a[k].minn[0]) ans += a[k].minn[0] - x;if(x > a[k].maxn[0]) ans += x - a[k].maxn[0];if(y < a[k].minn[1]) ans += a[k].minn[1] - y;if(y > a[k].maxn[1]) ans += y - a[k].maxn[1];return ans;
}
void query(int k , int x , int y)
{int dn = abs(x - a[k].p[0]) + abs(y - a[k].p[1]) , dl , dr;if(dn < ans) ans = dn;dl = a[k].c[0] ? getdis(a[k].c[0] , x , y) : inf;dr = a[k].c[1] ? getdis(a[k].c[1] , x , y) : inf;if(dl < dr){if(dl < ans) query(a[k].c[0] , x , y);if(dr < ans) query(a[k].c[1] , x , y);}else{if(dr < ans) query(a[k].c[1] , x , y);if(dl < ans) query(a[k].c[0] , x , y);}
}
int main()
{int n , m , i , opt , x , y;scanf("%d%d" , &n , &m);for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &a[i].p[0] , &a[i].p[1]);root = build(1 , n , 0);while(m -- ){scanf("%d%d%d" , &opt , &x , &y);if(opt == 1) n ++ , a[n].p[0] = a[n].maxn[0] = a[n].minn[0] = x , a[n].p[1] = a[n].maxn[1] = a[n].minn[1] = y , ins(n);else ans = inf , query(root , x , y) , printf("%d\n" , ans);}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/6934139.html

【bzoj2648】SJY摆棋子 KD-tree相关推荐

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

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

  2. BZOJ2648: SJY摆棋子

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

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

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

  4. [bzoj2648]SJY摆棋子(带插入kd-tree)

    解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  5. 天使玩偶/SJY摆棋子

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

  6. BZOJ 2648 SJY摆棋子(KD-Tree)

    题目链接:BZOJ 2648  SJY摆棋子 题意: 在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子.此处 ...

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

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

  8. [Luogu4169] [Violet]天使玩偶/SJY摆棋子 [cdq分治/k-d tree]

    [Link\frak{Link}Link] 考虑用 cdq 分治解决? 显然依旧分成修改跟查询,考虑一维排序二维cdq?啊但是那显然不太对,cdq能解决三维偏序, 但是她不能解决最近点对啊.平面最近点 ...

  9. 2716: [Violet 3]天使玩偶/2648: SJY摆棋子

    题目链接 题目大意:平面动态加点,求与给出的点曼哈顿距离最近点 题解:KD树模板题 我的收获:23333 #include <cstdio> #include <iostream&g ...

最新文章

  1. c语言中描述y是奇数,4章选择结构程序设计C语言入门习题
  2. linux下的python环境,linux下python环境
  3. php读取屏幕大小,jQuery 获取屏幕尺寸
  4. QDoc文字标记textmarkup
  5. 使用DatagramSocket与DatagramPacket传输数据
  6. 缓存穿透、缓存击穿和缓存雪崩
  7. 【渝粤题库】陕西师范大学201001 教育管理学(高起本)作业
  8. FPGA原语类型介绍
  9. “减压”成今年前十个月关键词:80后压力最大
  10. 共享代码库,为何总被程序员弃用?
  11. 像招程序员那样招司机,结果……
  12. vfp报表纸张设置_VFP报表输出.doc
  13. Informatic学习总结_day02
  14. python中自定义标识符_python标识符
  15. 你和你的女神之间,差了一个OpenCV口红色号识别器
  16. RedHat7.6 配置yum源
  17. 入手评测 戴尔游匣G15锐龙版 怎么样
  18. 【windows】window10打开图片显示黑屏,一直打不开
  19. word图片不显示或显示不全
  20. 51单片机生日快乐歌c语言,51单片机实现生日快乐歌

热门文章

  1. OpenCV中Kinect的使用(3)
  2. 不争气的geometry shader
  3. 无需用户输入,Adobe提出自动高质量图像合成新方法
  4. Fellow观点:AI框架下的医疗影像教学
  5. DeOccNet:国防科大提出阵列相机去除前景遮挡成像新方法
  6. 云智视像 | 内推两个年薪可达70万+的CV算法职位~base杭州上海
  7. 谷歌发布AdaNet,快速灵活的AutoML工具,帮助开发者构筑强大集成学习模型
  8. 《Python编程从入门到实践》记录之文件异常(try-except-else代码块)
  9. 《Python编程从入门到实践》记录之Python函数返回值
  10. wordpress安装到虚拟服务器,将WordPress安装在虚拟主机二级目录的方法