bzoj 2648: SJY摆棋子 (KD-tree)
2016-12-27 08:24
387 查看
2648: SJY摆棋子
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3152 Solved: 1078
[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 31 1
2 3
2 1 2
1 3 3
2 4 2
Sample Output
12
HINT
kdtree可以过
Source
鸣谢 孙嘉裕[Submit][Status][Discuss]
题解:KD-tree
KD-tree模板题
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define N 1000003 #define inf 2139062143 using namespace std; struct data { int d[2],mx[2],mn[2],l,r; }tr ; int n,m,cmpd,x,y,opt,ans,root; void update(int now) { int l=tr[now].l; int r=tr[now].r; if (l) { tr[now].mx[0]=max(tr[now].mx[0],tr[l].mx[0]); tr[now].mx[1]=max(tr[now].mx[1],tr[l].mx[1]); tr[now].mn[1]=min(tr[now].mn[1],tr[l].mn[1]); tr[now].mn[0]=min(tr[now].mn[0],tr[l].mn[0]); } if (r) { tr[now].mx[0]=max(tr[now].mx[0],tr[r].mx[0]); tr[now].mx[1]=max(tr[now].mx[1],tr[r].mx[1]); tr[now].mn[1]=min(tr[now].mn[1],tr[r].mn[1]); tr[now].mn[0]=min(tr[now].mn[0],tr[r].mn[0]); } } int cmp(data a,data b) { return a.d[cmpd]<b.d[cmpd]||a.d[cmpd]==b.d[cmpd]&&a.d[!cmpd]<b.d[!cmpd]; } int build(int l,int r,int d) { cmpd=d; int mid=(l+r)/2; nth_element(tr+l,tr+mid,tr+r+1,cmp); tr[mid].mx[0]=tr[mid].mn[0]=tr[mid].d[0]; tr[mid].mx[1]=tr[mid].mn[1]=tr[mid].d[1]; if (l!=mid) tr[mid].l=build(l,mid-1,d^1); if (r!=mid) tr[mid].r=build(mid+1,r,d^1); update(mid); return mid; } void insert(int now) { int p=root; int d=0; while (true) { tr[p].mx[0]=max(tr[p].mx[0],tr[now].mx[0]); tr[p].mx[1]=max(tr[p].mx[1],tr[now].mx[1]); tr[p].mn[1]=min(tr[p].mn[1],tr[now].mn[1]); tr[p].mn[0]=min(tr[p].mn[0],tr[now].mn[0]); if (tr[now].d[d]>=tr[p].d[d]) { if (!tr[p].r) { tr[p].r=now; return; }else p=tr[p].r; } else { if (!tr[p].l) { tr[p].l=now; return; } else p=tr[p].l; } d^=1; } } int dist(int now,int x,int y) { int dis=0; if (x<tr[now].mn[0]) dis+=tr[now].mn[0]-x; if (x>tr[now].mx[0]) dis+=x-tr[now].mx[0]; if (y<tr[now].mn[1]) dis+=tr[now].mn[1]-y; if (y>tr[now].mx[1]) dis+=y-tr[now].mx[1]; return dis; } void query(int now) { int dl,dr,d0; d0=abs(tr[now].d[0]-x)+abs(tr[now].d[1]-y); ans=min(ans,d0); if (tr[now].l) dl=dist(tr[now].l,x,y); else dl=inf; if (tr[now].r) dr=dist(tr[now].r,x,y); else dr=inf; if (dl<dr) { if (dl<ans) query(tr[now].l); if (dr<ans) query(tr[now].r); } else { if (dr<ans) query(tr[now].r); if (dl<ans) query(tr[now].l); } } int main() { freopen("a.in","r",stdin); //freopen("my.out","w",stdout); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d%d",&tr[i].d[0],&tr[i].d[1]); root=build(1,n,0); for (int i=1;i<=m;i++) { scanf("%d%d%d",&opt,&x,&y); if (opt==1) { ++n; tr .mx[0]=tr .mn[0]=tr .d[0]=x; tr .mx[1]=tr .mn[1]=tr .d[1]=y; insert(n); } else { ans=inf; query(root); printf("%d\n",ans); } } }
相关文章推荐
- [BZOJ]2648 SJY摆棋子 KD-Tree
- 【BZOJ2648】SJY摆棋子 [KD-tree]
- [bzoj2648/2716]SJY摆棋子_KD-Tree
- BZOJ 2648 SJY摆棋子(KD-Tree)
- KD_Tree 【bzoj2648 && bzoj2716】SJY摆棋子 && [voilet 3] 天使玩偶
- 【bzoj2648】SJY摆棋子 KD-tree
- BZOJ 2648 SJY摆棋子 ——KD-Tree
- bzoj2648 SJY摆棋子【KD-tree模板】
- [bzoj2648]SJY摆棋子【kd-tree】
- 【BZOJ2648】【kd_tree】SJY摆棋子
- [BZOJ2648] SJY摆棋子 kd-tree
- [KD-TREE] BZOJ 2648 SJY摆棋子 & BZOJ 2716 [Violet 3]天使玩偶
- [BZOJ2648]SJY摆棋子(kd-tree)
- BZOJ 2648/2716(SJY摆棋子-KD_Tree)[Template:KD_Tree]
- 【BZOJ2648】SYJ摆棋子 KD-Tree
- Bzoj2648:SJY摆棋子:K-D-Tree
- [BZOJ2648]SJY摆棋子(KD-tree+讲解)
- BZOJ 2648 SJY摆棋子 K-Dimensional-Tree
- BZOJ_P2648 SJY摆棋子&BZOJ_P2716 [Violet 3]天使玩偶(KD-Tree)
- BZOJ_2716_[Violet 3]天使玩偶&&BZOJ_2648_SJY摆棋子_KDTree