[APIO2018]选圆圈(KD-Tree)
2018-06-10 08:27
316 查看
题意:给你n个圆,每次选择半径最大的,将它和与它相交的圆全部删去,输出每个圆是在哪次被删的。
KD树模板题。用一个矩形框住这个圆,就可以直接剪枝了。为了防止被卡可以将点旋转一个角度,为了保险还可以多转几个角度。
#include<cmath> #include<cstdio> #include<algorithm> #define rep(i,l,r) for (int i=(l); i<=(r); i++) typedef double db; using namespace std; const int N=300010; const db inf=1e20,eps=1e-3,alpha=acos(-1)/3; int n,rt,ans ; db x,y,r; struct P{ db x,y,r; int id; }cur,a ; struct Tr{ int ls,rs; db x1,y1,x2,y2; P c; }T ; bool cmpx(const P &a,const P &b){ return a.x<b.x; } bool cmpy(const P &a,const P &b){ return a.y<b.y; } bool cmpr(const P &a,const P &b){ return (a.r==b.r) ? a.id<b.id : a.r>b.r; } void F(int x,int y){ T[x].x1=min(T[x].x1,T[y].x1); T[x].x2=max(T[x].x2,T[y].x2); T[x].y1=min(T[x].y1,T[y].y1); T[x].y2=max(T[x].y2,T[y].y2); } void upd(int x){ if (ans[T[x].c.id]) T[x].x1=T[x].y1=inf,T[x].x2=T[x].y2=-inf; else{ T[x].x1=T[x].c.x-T[x].c.r; T[x].x2=T[x].c.x+T[x].c.r; T[x].y1=T[x].c.y-T[x].c.r; T[x].y2=T[x].c.y+T[x].c.r; } if (T[x].ls) F(x,T[x].ls); if (T[x].rs) F(x,T[x].rs); } int build(int l,int r,int k){ if (l>r) return 0; int mid=(l+r)>>1; nth_element(a+l,a+mid,a+r+1,k?cmpy:cmpx); T[mid].c=a[mid]; T[mid].ls=build(l,mid-1,k^1); T[mid].rs=build(mid+1,r,k^1); upd(mid); return mid; } db sqr(db x){ return x*x; } bool Out(int x){ return (T[x].x2<cur.x-cur.r-eps) || (T[x].x1>cur.x+cur.r+eps) || (T[x].y2<cur.y-cur.r-eps) || (T[x].y1>cur.y+cur.r+eps); } bool chk(P &a){ return sqr(a.x-cur.x)+sqr(a.y-cur.y)<=sqr(a.r+cur.r)+eps; } void que(int x){ if (Out(x)) return; if (!ans[T[x].c.id] && chk(T[x].c)) ans[T[x].c.id]=cur.id; if (T[x].ls) que(T[x].ls); if (T[x].rs) que(T[x].rs); } int main(){ freopen("apiob.in","r",stdin); freopen("apiob.out","w",stdout); scanf("%d",&n); rep(i,1,n) scanf("%lf%lf%lf",&x,&y,&r),a[i]=(P){x*cos(alpha)+y*sin(alpha),y*cos(alpha)-x*sin(alpha),r,i}; rt=build(1,n,0); sort(a+1,a+n+1,cmpr); rep(i,1,n) if (!ans[a[i].id]) ans[a[i].id]=a[i].id,cur=a[i],que(rt); rep(i,1,n) printf("%d ",ans[i]); puts(""); return 0; }
相关文章推荐
- [APIO2018] Circle selection 选圆圈
- kD-tree 的C语言实现 带有史上最全的注释和解释
- [BZOJ4520][CQOI2016] K远点对 - KD-tree
- bzoj 2683: 简单题 (KD-tree)
- bzoj 4520: [Cqoi2016]K远点对(KD-tree)
- [BZOJ1941][Sdoi2010]Hide and Seek(KD-tree)
- [BZOJ4066]简单题(KD-tree)
- kd树简介 在matlab下VLFeat中的kd-tree使用
- PCL-Kd-Tree
- KD-Tree Python实现
- 使用kd-tree加速k-means
- PCL 点云索引方法K维树(KD-tree)和八叉树(octree)介绍
- 【kd-tree】bzoj2648 SJY摆棋子
- CTSC2018 && APIO2018 游记
- [bzoj2648/2716]SJY摆棋子_KD-Tree
- 【Trie】【kd-tree】计蒜客17122 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 I. Barty's Computer
- kd-tree搜索近邻点
- KD-Tree解决空间最短距离的利器
- BZOJ 3489 A simple rmq problem ——KD-Tree
- 【BZOJ2626】JZPFAR KDtree