[BZOJ2648] SJY摆棋子 kd-tree
2648: SJY摆棋子
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 5421 Solved: 1910
[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 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可以过
Source
kd-tree裸题
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstdio> 6 #include<algorithm> 7 #define maxn 1000001 8 using namespace std; 9 struct data { 10 int mn[2],mx[2],l,r,d[2]; 11 data() {mn[0]=mn[1]=mx[0]=mx[1]=l=r=d[0]=d[1]=0;} 12 }t[maxn*2]; 13 int n,m; 14 int nowd; 15 bool cmp(data t1,data t2) {return t1.d[nowd]==t2.d[nowd]?t1.d[!nowd]<t2.d[!nowd]:t1.d[nowd]<t2.d[nowd];} 16 void update(int x) { 17 if(t[x].l) { 18 t[x].mx[0]=max(t[x].mx[0],t[t[x].l].mx[0]); 19 t[x].mn[0]=min(t[x].mn[0],t[t[x].l].mn[0]); 20 t[x].mx[1]=max(t[x].mx[1],t[t[x].l].mx[1]); 21 t[x].mn[1]=min(t[x].mn[1],t[t[x].l].mn[1]); 22 } 23 if(t[x].r) { 24 t[x].mx[0]=max(t[x].mx[0],t[t[x].r].mx[0]); 25 t[x].mn[0]=min(t[x].mn[0],t[t[x].r].mn[0]); 26 t[x].mx[1]=max(t[x].mx[1],t[t[x].r].mx[1]); 27 t[x].mn[1]=min(t[x].mn[1],t[t[x].r].mn[1]); 28 } 29 } 30 int build(int l,int r,int D) { 31 int mid=l+r>>1; 32 nowd=D; 33 nth_element(t+l+1,t+mid+1,t+r+1,cmp); 34 if(l!=mid) t[mid].l=build(l,mid-1,!D); 35 if(r!=mid) t[mid].r=build(mid+1,r,!D); 36 t[mid].mx[0]=t[mid].mn[0]=t[mid].d[0]; 37 t[mid].mx[1]=t[mid].mn[1]=t[mid].d[1]; 38 update(mid); 39 return mid; 40 } 41 void insert(int &now,int D,data x) { 42 if(!now) {now=++n;t[now]=x;t[now].mn[0]=t[now].mx[0]=x.d[0];t[now].mx[1]=t[now].mn[1]=x.d[1];return;} 43 if(x.d[D]>t[now].d[D]) insert(t[now].r,!D,x); 44 else insert(t[now].l,!D,x); 45 update(now); 46 } 47 int dis(int now,data x) { 48 int re=0; 49 if(x.d[0]<t[now].mn[0]) re+=t[now].mn[0]-x.d[0]; 50 if(x.d[0]>t[now].mx[0]) re+=x.d[0]-t[now].mx[0]; 51 if(x.d[1]<t[now].mn[1]) re+=t[now].mn[1]-x.d[1]; 52 if(x.d[1]>t[now].mx[1]) re+=x.d[1]-t[now].mx[1]; 53 return re; 54 } 55 int ans; 56 void query(int now,data x) { 57 ans=min(ans,abs(t[now].d[0]-x.d[0])+abs(t[now].d[1]-x.d[1])); 58 int dl,dr; 59 if(t[now].l) dl=dis(t[now].l,x); else dl=2147483647; 60 if(t[now].r) dr=dis(t[now].r,x); else dr=2147483647; 61 if(dl<dr) { 62 if(dl<ans) query(t[now].l,x); 63 if(dr<ans) query(t[now].r,x); 64 } 65 else { 66 if(dr<ans) query(t[now].r,x); 67 if(dl<ans) query(t[now].l,x); 68 } 69 } 70 int main() { 71 scanf("%d%d",&n,&m); 72 for(int i=1;i<=n;i++) scanf("%d%d",&t[i].d[0],&t[i].d[1]); 73 int mid=build(1,n,0); 74 for(int i=1;i<=m;i++) { 75 int tp;data x; 76 scanf("%d%d%d",&tp,&x.d[0],&x.d[1]); 77 if(tp==1) insert(mid,0,x); 78 else {ans=2147483647;query(mid,x);printf("%d\n",ans);} 79 } 80 }
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~