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
Sample Output
1
2
HINT
kdtree可以过
解法:KDtree。可以看这篇博客学习KDtree.http://blog.csdn.net/jiangshibiao/article/details/34144829
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, root, D, op, x, y, ans;
struct node{
int d[2],l,r,mx[2],mi[2];
}a[800010];
inline int cmp(node a, node b){
return a.d[D]<b.d[D]||a.d[D]==b.d[D]&&a.d[D^1]<b.d[D^1];
}
inline void up(int k, int s){
a[k].mi[0] = min(a[k].mi[0], a[s].mi[0]);
a[k].mi[1] = min(a[k].mi[1], a[s].mi[1]);
a[k].mx[0] = max(a[k].mx[0], a[s].mx[0]);
a[k].mx[1] = max(a[k].mx[1], a[s].mx[1]);
}
int build(int l,int r,int dd){
D=dd; int mid=(l+r)/2;
nth_element(a+l+1,a+mid+1,a+r+1,cmp);
a[mid].mi[0]=a[mid].mx[0]=a[mid].d[0];
a[mid].mi[1]=a[mid].mx[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 dis = 0;
if(x<a[k].mi[0]) dis += a[k].mi[0]-x;
if(x>a[k].mx[0]) dis += x-a[k].mx[0];
if(y<a[k].mi[1]) dis += a[k].mi[1]-y;
if(y>a[k].mx[1]) dis += y-a[k].mx[1];
return dis;
}
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]);
root=build(1,n,0);
for(int i=1; i<=m; i++){
scanf("%d%d%d",&op,&x,&y);
if(op==1){
++n;
a[n].d[0]=a[n].mi[0]=a[n].mx[0]=x;
a[n].d[1]=a[n].mi[1]=a[n].mx[1]=y;
insert(n);
}else{
ans=inf;
ask(root);
printf("%d\n", ans);
}
}
return 0;
}