[BZOJ2648]SJY摆棋子-K-D树
2017-05-03 00:40
459 查看
SJY摆棋子
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可以过这个HINT真是良心~
但对于刚学K-D树的咱来说毫无意义……
告诉咱咱也写不出来……
(╯‵□′)╯︵┻━┻
思路:出题人都告诉你是K-D树了……
由于太弱无法通过定义脑补出K-D树,写出来的程序基本上和某黄学长的写法一模一样……
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int Inf=1000000000; int root,main_d,n,m; inline int read() { int x=0;char ch=getchar(); while(ch<'0' || '9'<ch)ch=getchar(); while('0'<=ch && ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x; } inline int maxx(int a,int b){if(a>b)return a;return b;} inline int minn(int a,int b){if(a>b)return b;return a;} struct point { int coord[2],mn[2],mx[2],l,r; int& operator [] (int x) { return coord[x]; } point(int x=0,int y=0) { l=0,r=0; coord[0]=x; coord[1]=y; } }p[500233]; bool operator < (point satori,point koishi) { return satori[main_d]<koishi[main_d]; } inline int getdis(point satori,point koishi) { return abs(satori[0]-koishi[0])+abs(satori[1]-koishi[1]); } struct k_dimensional_tree { int ans; point t[1000233],tmp; void update(int n) { int l=t .l,r=t .r; for(int i=0;i<2;i++) { if(l) { t .mn[i]=minn(t .mn[i],t[l].mn[i]); t .mx[i]=maxx(t .mx[i],t[l].mx[i]); } if(r) { t .mn[i]=minn(t .mn[i],t[r].mn[i]); t .mx[i]=maxx(t .mx[i],t[r].mx[i]); } } } int build(int l,int r,int now_d) { main_d=now_d; int mid=l+r>>1; nth_element(p+l,p+mid,p+r+1); t[mid]=p[mid]; for(int i=0;i<2;i++) t[mid].mn[i]=t[mid].mx[i]=t[mid][i]; if(l<mid) t[mid].l=build(l,mid-1,now_d^1); if(mid<r) t[mid].r=build(mid+1,r,now_d^1); update(mid); return mid; } int get(int n,point p) { int ret=0; for(int i=0;i<2;i++) ret+=maxx(0,t .mn[i]-p[i]) +maxx(0,p[i]-t .mx[i]); return ret; } void insert(int now,int now_d) { if(tmp[now_d]>=t[now][now_d]) { if(t[now].r) insert(t[now].r,now_d^1); else { t[now].r=++n; t =tmp; for(int i=0;i<2;i++) t .mn[i]=t .mx[i]=t [i]; } } else { if(t[now].l) insert(t[now].l,now_d^1); else { t[now].l=++n; t =tmp; for(int i=0;i<2;i++) t .mn[i]=t .mx[i]=t [i]; } } update(now); } void query(int n,int now_d) { int d,dl=Inf,dr=Inf; d=getdis(t ,tmp); ans=minn(ans,d); if(t .l) dl=get(t .l,tmp); if(t .r) dr=get(t .r,tmp); if(dl<dr) { if(dl<ans) query(t .l,now_d^1); if(dr<ans) query(t .r,now_d^1); } else { if(dr<ans) query(t .r,now_d^1); if(dl<ans) query(t .l,now_d^1); } } int query(point satori) { tmp=satori;ans=Inf; query(root,0); return ans; } void insert(point satori) { tmp=satori; insert(root,0); } }koishi; int main() { n=read(); m=read(); for(int i=1;i<=n;i++) p[i][0]=read(),p[i][1]=read(); root=koishi.build(1,n,0); for(int ii=1;ii<=m;ii++) { int tp=read(); int x=read(),y=read(); if(tp==1) koishi.insert(point(x,y)); else printf("%d\n",koishi.query(point(x,y))); } return 0; }
相关文章推荐
- BZOJ 2648 SJY摆棋子(KD Tree)
- BZOJ2648 SJY摆棋子
- BZOJ2648 SJY摆棋子
- [bzoj2648]SJY摆棋子【kd-tree】
- [BZOJ2648] SJY摆棋子 kd-tree
- 【BZOJ2716/2648】SJY摆棋子
- BZOJ 2648 SJY摆棋子 KDtree
- 【bzoj2648】SJY摆棋子
- [bzoj2648][kd树]SJY摆棋子
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
- BZOJ 2648 SJY摆棋子
- Bzoj2648 SJY摆棋子
- bzoj 2648 SJY摆棋子 kd树
- [BZOJ]2648 SJY摆棋子 KD-Tree
- bzoj2648 SJY摆棋子(不带修改的KDtree的学习)
- [BZOJ2648]=[BZOJ2716]SJY摆棋子
- BZOJ2648 - SJY摆棋子
- [BZOJ2648]SJY摆棋子(kd-tree)
- Bzoj2648:SJY摆棋子:K-D-Tree
- BZOJ2648 - SJY摆棋子