1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include<bits/stdc++.h> using namespace std; using ll=long long; #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); } template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); } char buf[200000],*p1,*p2; #define getchar() (((p1==p2)&&(p2=(p1=buf)+fread(buf,1,200000,stdin))),*p1++) char IO; int rd(){ int s=0,f=0; while(!isdigit(IO=getchar())) f=IO=='-'; do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return f?-s:s; } void wt(int x){ static int buf[10],l=0; while(x) buf[++l]=x%10+'0',x/=10; drep(i,l,1) putchar(buf[i]); l=0; }
const int N=3e5+10,INF=1e9+10;
int n,typ; struct Node{ ll x,y,r; int id; }A[N],B[N]; ll Dis(ll x,ll y,Node z){ return (x-z.x)*(x-z.x)+(y-z.y)*(y-z.y); } ll Dis(Node x,Node y){ return Dis(x.x,x.y,y); } int In(ll x,ll y,Node z){ return Dis(x,y,z)<=z.r*z.r; } int cmp(Node x,Node y){ return typ?x.x<y.x:x.y<y.y; } int c[N],ch[N][2],rt; int lx[N],rx[N],ly[N],ry[N]; void Up(int u) { if(c[B[u].id]) lx[u]=ly[u]=INF,rx[u]=ry[u]=-INF; else lx[u]=B[u].x-B[u].r,rx[u]=B[u].x+B[u].r,ly[u]=B[u].y-B[u].r,ry[u]=B[u].y+B[u].r; for(int v:ch[u]) if(v) cmin(lx[u],lx[v]),cmax(rx[u],rx[v]),cmin(ly[u],ly[v]),cmax(ry[u],ry[v]); }
int Get(int l,int r){ long double _x=0,_y=0,x=0,y=0; rep(i,l,r) _x+=B[i].x,_y+=B[i].y; _x/=r-l+1,_y/=r-l+1; rep(i,l,r) x+=(B[i].x-_x)*(B[i].x-_x),y+=(B[i].y-_y)*(B[i].y-_y); return x>y; }
int Build(int l,int r) { if(l>r) return 0; int u=(l+r)>>1; typ=Get(l,r),nth_element(B+l,B+u,B+r+1,cmp); ch[u][0]=Build(l,u-1),ch[u][1]=Build(u+1,r); return Up(u),u; } int Cross(int x,Node y){ if(lx[x]>rx[x]) return 0; if(In(lx[x],ly[x],y) || In(lx[x],ry[x],y) || In(rx[x],ly[x],y) || In(rx[x],ry[x],y)) return 1; if(lx[x]<=y.x && y.x<=rx[x] && ly[x]<=y.y && y.y<=ry[x]) return 1; if(lx[x]<=y.x && y.x<=rx[x]) if(In(y.x,ly[x],y) || In(y.x,ry[x],y)) return 1; if(ly[x]<=y.y && y.y<=ry[x]) if(In(lx[x],y.y,y) || In(rx[x],y.y,y)) return 1; return 0; } void Del(int u,Node x){ if(!u || !Cross(u,x)) return; if(!c[B[u].id] && Dis(x,B[u])<=(x.r+B[u].r)*(x.r+B[u].r)) c[B[u].id]=x.id; Del(ch[u][0],x),Del(ch[u][1],x); Up(u); }
int main(){ n=rd(); rep(i,1,n) { int x=rd(),y=rd(); A[i]=B[i]=(Node){x,y,rd(),i}; } sort(A+1,A+n+1,[&](Node x,Node y){ return x.r!=y.r?x.r>y.r:x.id<y.id;}),rt=Build(1,n); rep(i,1,n) if(!c[A[i].id]) Del(rt,A[i]); rep(i,1,n) printf("%d ",c[i]); }
|