BZOJ 2648: SJY摆棋子 kdtree
2016-11-24 18:33
405 查看
2648: SJY摆棋子
题目连接:
http://www.lydsy.com/JudgeOnline/problem.php?id=2648Description
这天,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 31 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
12
Hint
题意
题解:
kdtree裸题代码
#include<bits/stdc++.h> using namespace std; const int maxn = 1000005; #define INF 1000000000 struct arr{ int d[2],min[2],max[2],l,r; }; int D,root,x,y,ans,n,m,tot,op;; inline int cmp(arr a,arr b) { return a.d[D]<b.d[D]||a.d[D]==b.d[D]&&a.d[D^1]<b.d[D^1]; } arr a[maxn]; inline void up(int k,int s) { a[k].min[0]=min(a[k].min[0],a[s].min[0]); a[k].max[0]=max(a[k].max[0],a[s].max[0]); a[k].min[1]=min(a[k].min[1],a[s].min[1]); a[k].max[1]=max(a[k].max[1],a[s].max[1]); } int build(int l,int r,int dd) { D=dd;int mid=(l+r)>>1; nth_element(a+l+1,a+mid+1,a+r+1,cmp); a[mid].min[0]=a[mid].max[0]=a[mid].d[0]; a[mid].min[1]=a[mid].max[1]=a[mid].d[1]; if (l!=mid) a[mid].l=build(l,mid-1,dd^1); if (mid!=r) a[mid].r=build(mid+1,r,dd^1); if (a[mid].l) up(mid,a[mid].l); if (a[mid].r) up(mid,a[mid].r); return mid; } void insert(int k) { int p=root;D=0; while (1) { up(p,k); if (a[k].d[D]<=a[p].d[D]){if (!a[p].l) {a[p].l=k;return;} p=a[p].l;} else {if (!a[p].r) {a[p].r=k;return;} p=a[p].r;} D^=1; } } int getdis(int k) { int res=0; if (x<a[k].min[0]) res+=a[k].min[0]-x; if (x>a[k].max[0]) res+=x-a[k].max[0]; if (y<a[k].min[1]) res+=a[k].min[1]-y; if (y>a[k].max[1]) res+=y-a[k].max[1]; return res; } void ask(int k) { int d0=abs(a[k].d[0]-x)+abs(a[k].d[1]-y); if (d0<ans) ans=d0; int dl=(a[k].l)?getdis(a[k].l):INF; int dr=(a[k].r)?getdis(a[k].r):INF; if (dl<dr){if (dl<ans) ask(a[k].l);if (dr<ans) ask(a[k].r);} else {if (dr<ans) ask(a[k].r);if (dl<ans) ask(a[k].l);} } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].d[0],&a[i].d[1]); } if(n)root = build(1,n,0); for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ n++; scanf("%d%d",&a .d[0],&a .d[1]); a .min[0]=a .max[0]=a .d[0]; a .min[1]=a .max[1]=a .d[1]; insert(n); }else if(op==2){ ans=2000000000; scanf("%d%d",&x,&y); ask(root); printf("%d\n",ans); } } }
相关文章推荐
- 【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)
- 【BZOJ2648】SJY摆棋子 KDTree 【数组版!】
- BZOJ 2648 SJY摆棋子 KDtree
- BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree
- bzoj2648 SJY摆棋子(不带修改的KDtree的学习)
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
- BZOJ 2648: SJY摆棋子/BZOJ 2716: [Violet 3]天使玩偶 kdtree
- 【BZOJ2648】SJY摆棋子 KDtree
- BZOJ2648 - SJY摆棋子
- BZOJ 2648 SJY摆棋子 / 2716 Violet 3 天使玩偶 K-D树
- bzoj2648 SJY摆棋子
- 【34.25%】【BZOJ 2648】SJY摆棋子
- [bzoj2648/2716]SJY摆棋子
- BZOJ 2648/2716(SJY摆棋子-KD_Tree)[Template:KD_Tree]
- BZOJ2648 - SJY摆棋子
- 【bzoj2648】SJY摆棋子
- bzoj2648 SJY摆棋子
- bzoj 2648: SJY摆棋子
- [BZOJ2648]SJY摆棋子-K-D树
- 【BZOJ2716/2648】SJY摆棋子