您的位置:首页 > 其它

[BZOJ2648] SJY摆棋子 kd-tree

2018-02-05 15:01 453 查看

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: