#include #define ff first #define ss second #define pb push_back #define ll long long using namespace std; typedef pair pii; typedef pair pdi; const int maxn=1e5+10; const int maxk=1e5+10; const int maxa=1e9+10; const int max_speed_segments=10; const int max_binary_iterations=20; const int brute_lim=1000; pdi speed[maxk]; int grp[maxk]; double max_speed,min_speed; struct point{ int x,y; point(){ x=y=0; } point(int x,int y){ this->x=x; this->y=y; } double dist(point b){ return sqrt(((double)x-b.x)*((double)x-b.x)+((double)y-b.y)*((double)y-b.y));/// OVO MOZDA VRATITI NA DOUBLE } /*double sqdist(point b){ return ((double)x-b.x)*((double)x-b.x)+((double)y-b.y)*((double)y-b.y); }*/ void ispis(){ printf("%d %d\n",x,y); } }pts[maxn]; int n,k; struct scaller{ vectora; scaller(){} scaller(vectorb){ a=b; a.pb(-maxa*2+10); a.pb(maxa*2+10); sort(a.begin(),a.end()); a.resize( unique(a.begin(),a.end())-a.begin() ); } int get_scalled(int x){ int pos=lower_bound(a.begin(),a.end(),x)-a.begin(); if(a[pos]!=x)return -1; return pos+1; } int get_real(int x){ return a[x-1]; } int get_loweq(int x){ int l=0; int r=a.size(); int sr,ret=-1; while(l<=r){ sr=(l+r)/2; if(a[sr]<=x){ l=sr+1; ret=sr; } else r=sr-1; } return ret+1; } int get_higheq(int x){ int l=0; int r=a.size(); int sr,ret=-1; while(l<=r){ sr=(l+r)/2; if(a[sr]>=x){ r=sr-1; ret=sr; } else l=sr+1; } return ret+1; } }x_scaler,y_scaler; struct solution{ vectora; double score; void calc_score(){ score=0; vectorprv(k,-1); for(int i=0;ib){ a=b; score=2e18; calc_score(); } void ispis(){ vectorbegpt(k); ///printf("ISPAO %d\n",a.size()); ///cout<sz; } pnode root=NULL; int *pos; void build(pnode &x,int l,int r,vector&v,int tip){ if(l>r)return; if(x==NULL)x=new node(); if(tip==0)sort( (&v[0])+l,(&v[0])+r+1, srt_x ); else sort( (&v[0])+l,(&v[0])+r+1, srt_y ); int mid=(l+r)/2; x->pid=v[mid]; build(x->l,l,mid-1,v,tip^1); build(x->r,mid+1,r,v,tip^1); } void re_build(pnode &r,pnode x){ if(x==NULL)return; r=new node(); r->pid=x->pid; re_build(r->l,x->l); re_build(r->r,x->r); } seg_points(seg_points *p){ if(p==NULL){ vectorv(n); for(int i=0;iroot); } } void upd1(pnode x,int px,int py,int val,int tip,bool invert){ if(x==NULL){ printf("Auf...\n"); x->pid=1; return; } if(pts[x->pid].x==px && pts[x->pid].y==py){ if(!invert){ x->runner_id=val; x->flag=1; x->sz++; } else{ x->runner_id=-1; x->flag=0; x->sz--; } return; } int qx=pts[x->pid].x; int qy=pts[x->pid].y; if(tip==0){ if( (pxl,px,py,val,tip^1,invert); else upd1(x->r,px,py,val,tip^1,invert); } else{ if( (pyl,px,py,val,tip^1,invert); else upd1(x->r,px,py,val,tip^1,invert); } x->sz=sz(x->l)+sz(x->r)+x->flag; } void update(int x,int y,int runner,bool invert){ upd1(root,x,y,runner,0,invert); } void check(int x,int y,int &best,int qr){ if(best==-1){ best=qr; return; } int id1=pos[best]; int id2=pos[qr]; point f(x,y); double pom1=pts[id1].dist(f)*speed[best].ff; double pom2=pts[id2].dist(f)*speed[qr].ff; if(pom1>pom2)best=qr; } void qry(pnode x,int px,int py,int tip,int &best){ if(x==NULL)return; if(x->sz==0)return; ///printf("%d | %d %d | %d %d\n",x->pid,pts[x->pid].x,pts[x->pid].y,px,py ); int qx=pts[x->pid].x; int qy=pts[x->pid].y; if(x->flag)check(px,py,best,x->runner_id); pnode nxt_node; pnode other_node; if(tip==0){ if( (pxl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } else{ if( (pyl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } qry(nxt_node,px,py,tip^1,best); if(best==-1){ qry(other_node,px,py,tip^1,best); } else{ double d; if(tip==0){ d=abs(pts[pos[best]].x-pts[x->pid].x); } else{ d=abs(pts[pos[best]].y-pts[x->pid].y); } point pom(px,py); ///cout<pid].y)<<" "<<(pts[pos[best]].x-pts[x->pid].x)<pom2)best=qr; } void qry2(pnode x,int px,int py,int tip,int &best){ if(x==NULL)return; if(x->sz==0)return; ///printf("%d | %d %d | %d %d\n",x->pid,pts[x->pid].x,pts[x->pid].y,px,py ); int qx=pts[x->pid].x; int qy=pts[x->pid].y; if(x->flag)check2(px,py,best,x->pid); pnode nxt_node; pnode other_node; if(tip==0){ if( (pxl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } else{ if( (pyl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } qry2(nxt_node,px,py,tip^1,best); if(best==-1){ qry2(other_node,px,py,tip^1,best); } else{ double d; if(tip==0){ d=abs(pts[best].x-pts[x->pid].x); } else{ d=abs(pts[best].y-pts[x->pid].y); } point pom(px,py); ///cout<pid].y)<<" "<<(pts[pos[best]].x-pts[x->pid].x)<sz==0)return; ///printf("%d | %d %d | %d %d\n",x->pid,pts[x->pid].x,pts[x->pid].y,px,py ); int qx=pts[x->pid].x; int qy=pts[x->pid].y; if(x->flag)check_max(px,py,best,x->pid); pnode nxt_node; pnode other_node; if(tip==0){ if( (pxl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } else{ if( (pyl; other_node=x->r; } else{ nxt_node=x->r; other_node=x->l; } } swap(nxt_node,other_node); max_qry(nxt_node,px,py,tip^1,best,0); if(onpath || sz(nxt_node)==0)max_qry(other_node,px,py,tip^1,best,1); /*if(best==-1){ qry(other_node,px,py,tip^1,best); } else{ double d; if(tip==0)d= abs((ll)pts[pos[best]].x-pts[x->pid].x); else d= abs((ll)pts[pos[best]].y-pts[x->pid].y); point pom(px,py); if(dflag=0; x->runner_id=-1; x->sz=0; go_reset(x->l); go_reset(x->r); } void reset(){ go_reset(root); } }*structure[max_speed_segments+1]; int get_grp(int runner){ double d=(max_speed-min_speed)/max_speed_segments; return (int)( (speed[runner].ff-min_speed)/d ); } void input(){ freopen("runners.in","r",stdin); freopen("runners.out","w",stdout); scanf("%d %d",&n,&k); max_speed=0; min_speed=10; for(int i=0;i>speed[i].ff; speed[i].ss=i; max_speed=max(max_speed,speed[i].ff); min_speed=min(min_speed,speed[i].ff); } ///sort(speed+1,speed+n+1); if(max_speed-min_speed<1)max_speed+=1; for(int i=0;i0)cout<xx,yy; for(int i=0;i&v){ int prefix_lim=min(k,1); if(k<=10000)prefix_lim=k; int window=k*4; vector >cand; for(int i=0;i=prefix_lim){ int ppom=structure[0]->query2(pts[i].x,pts[i].y); cand.pb({pts[ppom].dist(pts[i]),i}); } else{ v[i]=1; } if(i-window<0){} else{ structure[0]->update(pts[i-window].x,pts[i-window].y,0,1); } structure[0]->update(pts[i].x,pts[i].y,0,0); } sort(cand.begin(),cand.end()); for(int i=0;ipom_speed; for(int i=0;itake(n,0); calc_take(take); for(int i=0;i<=max_speed_segments;i++) structure[i]->reset(); int currk=0; vectorret,prv(k,-1); for(int i=0;i<=max_speed_segments;i++) structure[i]->pos=(&prv[0]); /*for(int i=0;iupdate(pts[prv[i]].x,pts[prv[i]].y,i,0); }*/ currk=0; for(int i=0;iupdate(pts[i].x,pts[i].y,id,0); prv[id]=i; ret.pb(id); currk++; continue; } vectorcand; if(currk>brute_lim){ for(int j=0;j<=max_speed_segments;j++){ ///cout<query(pts[i].x,pts[i].y); if(pom!=-1)cand.pb(pom); ///printf("%d %d CC\n",j,pom); } } if(currk<=brute_lim){ for(int j=0;jupdate(pts[prv[mink]].x,pts[prv[mink]].y,mink,1); prv[mink]=i; ret.pb(mink); structure[grp[mink]]->update(pts[prv[mink]].x,pts[prv[mink]].y,mink,0); /// printf("%d RET\n",ret.back()); } ///printf("\n"); solution r(ret); ///printf("OPALA\n"); /// cout<