Submission #78069

#TimeUsernameProblemLanguageResultExecution timeMemory
78069autumn_eelCircle selection (APIO18_circle_selection)C++14
100 / 100
734 ms39840 KiB
#include <bits/stdc++.h> #define rep(i,n)for(int i=0;i<(n);i++) #define INF INT_MAX using namespace std; typedef long long ll; int ans[400000]; struct Circle{ int x,y,r; int id; int bbox[2][2]; Circle(){} Circle(int x,int y,int r,int id):x(x),y(y),r(r),id(id){ bbox[0][0]=x-r;bbox[0][1]=y-r; bbox[1][0]=x+r;bbox[1][1]=y+r; } }; vector<Circle*>circle; struct node{ int bbox[2][2]; node*l,*r; Circle*circle; }; void init(int bbox[2][2]){ bbox[0][0]=bbox[0][1]=INF; bbox[1][0]=bbox[1][1]=-INF; } void mergeAABB(int bbox[2][2],int bbox2[2][2],int result[2][2]){ rep(i,2){ result[0][i]=min(bbox[0][i],bbox2[0][i]); result[1][i]=max(bbox[1][i],bbox2[1][i]); } } void createAABB(int l,int r,int result[2][2]){ init(result); for(int i=l;i<r;i++){ mergeAABB(result,circle[i]->bbox,result); } } node bvh[800000]; int pointer=0; inline void setleaf(int l,node*n){ n->l=n->r=NULL; n->circle=circle[l]; } void build(int l,int r,node*n,int depth){ createAABB(l,r,n->bbox); if(r-l==1){ setleaf(l,n); return; } int axis=-1; int minx=INF,maxx=-INF,miny=INF,maxy=-INF; for(int i=l;i<r;i++){ minx=min(minx,circle[i]->bbox[0][0]); maxx=max(maxx,circle[i]->bbox[1][0]); miny=min(miny,circle[i]->bbox[0][1]); maxy=max(maxy,circle[i]->bbox[1][1]); } if(maxx-minx>maxy-miny)axis=0; else axis=1; n->l=&bvh[pointer++]; n->r=&bvh[pointer++]; int id=(r+l)/2; nth_element(circle.begin()+l,circle.begin()+id,circle.begin()+r,[&](auto a,auto b){ if(axis==0)return a->x<b->x; return a->y<b->y; }); build(l,id,n->l,depth+1); build(id,r,n->r,depth+1); } inline ll sq(int x){ return x*(ll)x; } inline bool intersect(Circle*c1,Circle*c2){ return sq(c1->x-c2->x)+sq(c1->y-c2->y)<=sq(c1->r+c2->r); } inline bool intersect(int bbox1[2][2],int bbox2[2][2]){ if(bbox1[1][0]<bbox2[0][0]||bbox2[1][0]<bbox1[0][0]||bbox1[1][1]<bbox2[0][1]||bbox2[1][1]<bbox1[0][1])return false; return true; } node*intersect(node*n,Circle*c){ if(!intersect(c->bbox,n->bbox))return n; if(n->l){ auto l=intersect(n->l,c); auto r=intersect(n->r,c); if(l==NULL&&r==NULL)return NULL; if(l==NULL)return r; if(r==NULL)return l; n->l=l;n->r=r; init(n->bbox); mergeAABB(l->bbox,r->bbox,n->bbox); return n; } else{ if(intersect(n->circle,c)){ ans[n->circle->id]=c->id; return NULL; } return n; } } //~ #define DEBUG Circle c[400000]; int main(){ #ifdef DEBUG auto start=chrono::system_clock::now(); #endif int n;scanf("%d",&n); rep(i,n){ int x,y,r;scanf("%d%d%d",&x,&y,&r); c[i]=Circle(x,y,r,i); } sort(c,c+n,[](auto a,auto b){ if(a.r==b.r)return a.id<b.id; return a.r>b.r; }); rep(i,n){ circle.push_back(&c[i]); } node*root=&bvh[pointer++]; build(0,circle.size(),root,0); #ifdef DEBUG auto end=chrono::system_clock::now(); double tim=chrono::duration_cast<chrono::milliseconds>(end-start).count(); printf("build time = %.3lf sec\n",tim/1000); #endif memset(ans,-1,sizeof(ans)); rep(i,n){ if(ans[c[i].id]!=-1)continue; root=intersect(root,&c[i]); if(root==NULL)break; } #ifndef DEBUG rep(i,n){ if(i)printf(" "); printf("%d",ans[i]+1); } puts(""); #endif #ifdef DEBUG auto end2=chrono::system_clock::now(); double tim2=chrono::duration_cast<chrono::milliseconds>(end2-end).count(); printf("intersection time = %.3lf sec\n",tim2/1000); double tim3=chrono::duration_cast<chrono::milliseconds>(end2-start).count(); printf("total time = %.3lf sec\n",tim3/1000); #endif }

Compilation message (stderr)

circle_selection.cpp: In function 'int main()':
circle_selection.cpp:113:13: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int n;scanf("%d",&n);
        ~~~~~^~~~~~~~~
circle_selection.cpp:115:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int x,y,r;scanf("%d%d%d",&x,&y,&r);
             ~~~~~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...