BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree
来源:互联网 发布:mac基于linux还是unix 编辑:程序博客网 时间:2024/05/22 03:16
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
1 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
1
2
HINT
kdtree可以过
传送门
双倍经验hhh
此题似乎是kdtree的裸题= =
询问最坏是O(根号n)的,
就是插入可能最坏会O(n)吧,不行可以重构……但是其实还是会T的感觉。。
一开始网上很多题解的曼哈顿距离记录了max,min啥的不是很明白。
现在感觉就是一个启发式搜索。
维护当前切割的平面里面的二维坐标的最值,共4个。
然后搜索答案的时候可以判断两个平面内的dist,然后启发式地走哪一边。
感觉有点说不大清楚……max,min就是维护某一个切割平面内的坐标的最值。
画个图会更加明显一点的。
代码部分我不太行……
借鉴了orz的代码。
调着调着就几乎和他一样了……(笑哭)
卡常?不存在的= =
#include<bits/stdc++.h>#define ll long longusing namespace std;int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}const int N=500005,inf=2000000000;int n,m,t,ans,root;struct POINT{int Dim[2],MAX[2],MIN[2],l,r;}point[N+N],T;bool cmp(POINT x,POINT y){return x.Dim[t]<y.Dim[t];}int dist(int u,int x,int y){int dis=0;if (x<point[u].MIN[0]) dis+=point[u].MIN[0]-x;if (x>point[u].MAX[0]) dis+=x-point[u].MAX[0];if (y<point[u].MIN[1]) dis+=point[u].MIN[1]-y;if (y>point[u].MAX[1]) dis+=y-point[u].MAX[1];return dis;}void up(int u){if (point[u].l){point[u].MAX[0]=max(point[u].MAX[0],point[point[u].l].MAX[0]);point[u].MAX[1]=max(point[u].MAX[1],point[point[u].l].MAX[1]);point[u].MIN[0]=min(point[u].MIN[0],point[point[u].l].MIN[0]);point[u].MIN[1]=min(point[u].MIN[1],point[point[u].l].MIN[1]);}if (point[u].r){point[u].MAX[0]=max(point[u].MAX[0],point[point[u].r].MAX[0]);point[u].MAX[1]=max(point[u].MAX[1],point[point[u].r].MAX[1]);point[u].MIN[0]=min(point[u].MIN[0],point[point[u].r].MIN[0]);point[u].MIN[1]=min(point[u].MIN[1],point[point[u].r].MIN[1]);}}int build(int L,int R,int now){int mid=(L+R)>>1;t=now;nth_element(point+L,point+mid,point+R+1,cmp);point[mid].MAX[0]=point[mid].MIN[0]=point[mid].Dim[0];point[mid].MAX[1]=point[mid].MIN[1]=point[mid].Dim[1];if (L!=mid) point[mid].l=build(L,mid-1,now^1);if (R!=mid) point[mid].r=build(mid+1,R,now^1);up(mid);return mid;}void insert(int id){int now=0,p=root;while (1){point[p].MAX[0]=max(point[id].MAX[0],point[p].MAX[0]);point[p].MAX[1]=max(point[id].MAX[1],point[p].MAX[1]);point[p].MIN[0]=min(point[id].MIN[0],point[p].MIN[0]);point[p].MIN[1]=min(point[id].MIN[1],point[p].MIN[1]);if (point[id].Dim[now]<=point[p].Dim[now])if (!point[p].l){point[p].l=id;return;} else p=point[p].l; else if (!point[p].r){point[p].r=id;return;} else p=point[p].r;now^=1;}}void query(int id){int d0,dl,dr;d0=abs(T.Dim[0]-point[id].Dim[0])+abs(T.Dim[1]-point[id].Dim[1]);if (ans>d0) ans=d0;if (point[id].l) dl=dist(point[id].l,T.Dim[0],T.Dim[1]); else dl=inf;if (point[id].r) dr=dist(point[id].r,T.Dim[0],T.Dim[1]); else dr=inf;if (dl<dr){if (dl<ans) query(point[id].l);if (dr<ans) query(point[id].r);} else{if (dr<ans) query(point[id].r);if (dl<ans) query(point[id].l);}}int main(){n=read(),m=read();for (int i=1;i<=n;i++)point[i].Dim[0]=read(),point[i].Dim[1]=read();root=build(1,n,0);while (m--){int opt=read();T.Dim[0]=read(),T.Dim[1]=read();if (opt==1){n++;point[n].MAX[0]=point[n].MIN[0]=point[n].Dim[0]=T.Dim[0];point[n].MAX[1]=point[n].MIN[1]=point[n].Dim[1]=T.Dim[1];insert(n);} else{ans=inf,query(root);printf("%d\n",ans);}}return 0;}
阅读全文
0 0
- [KD-TREE] BZOJ 2648 SJY摆棋子 & BZOJ 2716 [Violet 3]天使玩偶
- BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶 SJY摆棋子
- BZOJ 2648: SJY摆棋子/BZOJ 2716: [Violet 3]天使玩偶 kdtree
- BZOJ_P2648 SJY摆棋子&BZOJ_P2716 [Violet 3]天使玩偶(KD-Tree)
- BZOJ 2648 SJY摆棋子 / 2716 Violet 3 天使玩偶 K-D树
- 2648: SJY摆棋子/2716: [Violet 3]天使玩偶 K-D tree
- 【bzoj2648&bzoj2716】[Violet 3]天使玩偶&SJY摆棋子【kd树】
- 2716: [Violet 3]天使玩偶&&2648: SJY摆棋子|K-DTree
- [BZOJ]2648 SJY摆棋子 KD-Tree
- 【BZOJ】【P2648&P2716】【SJY摆棋子】【天使玩偶】【题解】【kdtree】
- bzoj 2648: SJY摆棋子 (KD-tree)
- bzoj 2648: SJY摆棋子(kd tree)
- 【BZOJ 2716&2648】[Violet 3]天使玩偶 k-d tree
- KD_Tree 【bzoj2648 && bzoj2716】SJY摆棋子 && [voilet 3] 天使玩偶
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶
- bzoj2648&2716 SJY摆棋子 (Kd-Tree)
- [BZOJ2648]SJY摆棋子(kd-tree)
- java服务器端图片转换webp以及批量转换webp脚本
- pat 乙级 1035. 插入与归并(25)
- POJ 2485 Highways 笔记
- Java程序员的必备知识-类加载机制详解
- Linux学习(七)网络配置
- BZOJ 2648/2716 SJY摆棋子/[Violet 3]天使玩偶 kd tree
- 虚拟路由冗余协议VRRP
- StringUtils详细介绍
- [3]48. Rotate Image(Java)
- go处理字符串
- 大话android 进程通信之AIDL
- Redis五种数据类型介绍
- Redis事务介绍
- 【Linux相识相知】任务计划和周期性任务