[BZOJ2648] SJY摆棋子 kd-tree

2648: SJY摆棋子

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 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

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 }
View Code

 

posted @ 2018-02-05 15:01  wls001  阅读(172)  评论(0编辑  收藏  举报