Submission #49614

#TimeUsernameProblemLanguageResultExecution timeMemory
49614DiuvenCircle selection (APIO18_circle_selection)C++11
49 / 100
3051 ms66736 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; const int MX=300010, inf=2e9; struct CIRCLE { int x, y, r, idx, kill; } C[MX]; inline ll sq(ll x){ return x*x; } inline ll dist(int a, int b){ return sq(C[a].x-C[b].x)+sq(C[a].y-C[b].y); } inline bool hit(int a, int b){ return dist(a,b)<=sq(C[a].r+C[b].r); } int n; void input(){ cin>>n; for(int i=1; i<=n; i++){ int x, y, r; cin>>x>>y>>r; C[i]={x,y,r,i,0}; } } vector<vector<vi>> G; ll t=1<<30; // [-t, 0), [0, t) inline int sect(int idx, int x0, int y0){ // 1 3 // 0 2 int x=C[idx].x, y=C[idx].y; if(x<x0) if(y<y0) return 0; else return 1; else if(y<y0) return 2; else return 3; } inline int range(ll x){ if(x>0) return x/t; return -((-x+t-1)/t); } inline int xrange(const vi &cell){ return range(C[cell.front()].x); } inline int yrange(const vi &cell){ return range(C[cell.front()].y); } inline int xrange(const vector<vi> &X){ return xrange(X.front()); } void init_grid(){ vi V[4]; for(int i=1; i<=n; i++){ V[sect(i,0,0)].push_back(i); } vector<vi> X[2]; for(int k=0; k<4; k++) if(!V[k].empty()) X[k/2].push_back(V[k]); if(!X[0].empty()) G.push_back(X[0]); if(!X[1].empty()) G.push_back(X[1]); } void resize_grid(){ vector<vector<vi>> tmp; for(auto &X:G){ vector<vi> newX[2]; for(vi &cell:X){ vi V[4]; int x=xrange(cell)*t + t/2; int y=yrange(cell)*t + t/2; for(int idx:cell){ if(C[idx].kill!=0) continue; V[sect(idx,x,y)].push_back(idx); } for(int k=0; k<4; k++) if(!V[k].empty()) newX[k/2].push_back(V[k]); } if(!newX[0].empty()) tmp.push_back(newX[0]); if(!newX[1].empty()) tmp.push_back(newX[1]); } // slow!!! G=tmp; t/=2; } void process(vi &cell, int killer){ vi tmp; for(int killed:cell){ if(C[killed].kill==0 && hit(killed, killer)) C[killed].kill=killer; if(C[killed].kill==0) tmp.push_back(killed); } cell=tmp; } void kill(int idx){ while(C[idx].r*2<t){ resize_grid(); } int x=C[idx].x, y=C[idx].y; ll lx=range(x)-2, hx=range(x)+3; ll ly=range(y)-2, hy=range(y)+3; int n1=G.size(); int s1=0, e1=n1-1; while(s1<e1){ int m1=(s1+e1)/2; if(xrange(G[m1])<lx) s1=m1+1; else e1=m1; } int pos=s1; while(pos<min(n1,s1+5) && lx<=xrange(G[pos]) && xrange(G[pos])<=hx){ vector<vi> &X=G[pos]; int n2=X.size(); int s2=0, e2=n2-1; while(s2<e2){ int m2=(s2+e2)/2; if(yrange(X[m2])<ly) s2=m2+1; else e2=m2; } while(s2<n2 && ly<=yrange(X[s2]) && yrange(X[s2])<=hy){ process(X[s2], idx); s2++; } pos++; } } void solve(){ CIRCLE D[MX]; for(int i=1; i<=n; i++) D[i]=C[i]; sort(D+1, D+n+1, [](CIRCLE &a, CIRCLE &b){ if(a.r==b.r) return a.idx<b.idx; return a.r>b.r; }); for(int i=1; i<=n; i++){ int idx=D[i].idx; if(C[idx].kill!=0) continue; kill(idx); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); input(); init_grid(); solve(); for(int i=1; i<=n; i++) cout<<C[i].kill<<' '; return 0; }
#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...