bzoj2648 SJY摆棋子 k-d树
2018-01-19 07:16
369 查看
Description
这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。kdtree可以过
Solution
hint已经很良心了,这题实际上和2714是一样的,练手Code
#include <stdio.h> #include <string.h> #include <algorithm> #define rep(i,st,ed) for (int i=st;i<=ed;++i) #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) const int INF=0x3f3f3f3f; const int N=1000005; struct treeNode{int d[2],min[2],max[2],l,r;}t ; int D,root,ans; int read() { int x=0,v=1; char ch=getchar(); for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar()); for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar()); return x*v; } bool cmp(treeNode a,treeNode b) {return a.d[D]<b.d[D]||a.d[D]==b.d[D]&&a.d[D^1]<b.d[D^1];} void update(int x,int y) { t[x].min[0]=min(t[x].min[0],t[y].min[0]); t[x].min[1]=min(t[x].min[1],t[y].min[1]); t[x].max[0]=max(t[x].max[0],t[y].max[0]); t[x].max[1]=max(t[x].max[1],t[y].max[1]); } int get_dis(int now,int x,int y) { int ret=0; ret+=max(0,x-t[now].max[0]); ret+=max(0,t[now].min[0]-x); ret+=max(0,y-t[now].max[1]); ret+=max(0,t[now].min[1]-y); return ret; } void query(int now,int x,int y) { int w=std:: abs(t[now].d[0]-x)+std:: abs(t[now].d[1]-y); int dl=INF,dr=INF; ans=min(w,ans); if (t[now].l) dl=get_dis(t[now].l,x,y); if (t[now].r) dr=get_dis(t[now].r,x,y); if (dl<dr) { if (dl<ans) query(t[now].l,x,y); if (dr<ans) query(t[now].r,x,y); } else { if (dr<ans) query(t[now].r,x,y); if (dl<ans) query(t[now].l,x,y); } } void ins(int x) { int now=root; D=0; while (233) { update(now,x); if (t[x].d[D]<=t[now].d[D]) { if (!t[now].l) {t[now].l=x; return ;} now=t[now].l; } else { if (!t[now].r) {t[now].r=x; return ;} now=t[now].r; } D^=1; } } int buildTree(int l,int r,int dd) { D=dd; int mid=(l+r)>>1; std:: nth_element(t+l,t+mid,t+r+1,cmp); t[mid].min[0]=t[mid].max[0]=t[mid].d[0]; t[mid].min[1]=t[mid].max[1]=t[mid].d[1]; if (l<mid) t[mid].l=buildTree(l,mid-1,dd^1); if (mid<r) t[mid].r=buildTree(mid+1,r,dd^1); if (t[mid].l) update(mid,t[mid].l); if (t[mid].r) update(mid,t[mid].r); return mid; } int main(void) { int n=read(),m=read(); rep(i,1,n) { t[i].d[0]=read(); t[i].d[1]=read(); } root=buildTree(1,n,0); rep(i,1,m) { int opt=read(),x=read(),y=read(); if (opt==1) { n++; t .min[0]=t .max[0]=t .d[0]=x; t .min[1]=t .max[1]=t .d[1]=y; ins(n); } else { ans=INF; query(root,x,y); printf("%d\n", ans); } } return 0; }
相关文章推荐
- 【bzoj2648】 SJY摆棋子
- [BZOJ2648]SJY摆棋子(KD-tree+讲解)
- 【BZOJ】【2648】SJY摆棋子&【BZOJ】【2716】【Violet 3】天使玩偶
- BZOJ 2648 SJY摆棋子
- bzoj2648 SJY摆棋子
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶 SJY摆棋子
- 【BZOJ2716/2648】SJY摆棋子
- 【BZOJ2648】SJY摆棋子
- BZOJ 2648: SJY摆棋子
- 【bzoj2648】SJY摆棋子
- [bzoj2648]SJY摆棋子【kd-tree】
- BZOJ2648 SJY摆棋子
- [BZOJ2648] SJY摆棋子 kd-tree
- BZOJ 2648 SJY摆棋子
- BZOJ 2648 SJY摆棋子 K-Dimensional-Tree
- Bzoj2648 SJY摆棋子
- HYSBZ bzoj 2648 SJY摆棋子
- 【BZOJ2648】【kd_tree】SJY摆棋子
- BZOJ 2648 SJY摆棋子(KD树)
- bzoj 2648 SJY摆棋子 kd树