Submission #354549

#TimeUsernameProblemLanguageResultExecution timeMemory
354549IloveNCircle selection (APIO18_circle_selection)C++14
72 / 100
3032 ms395744 KiB
#pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx,avx2,fma") #include<bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define all(vr) vr.begin(),vr.end() #define vi vector<int> #define vll vector<ll> const int N=3e5+10; const ll inf=1e9; struct circle{int x,y,r,id;}; circle a[N]; int n; pii X[N],Y[N]; int ans[N]; ll sqr(ll x) { return x*x;} bool intersect(int i,int j) { return sqr(a[i].x-a[j].x)+sqr(a[i].y-a[j].y)<=sqr(a[i].r+a[j].r); } struct segment_tree_2d { vi pre[N*4],nex[N*4],pos_in[N],bit[N*4]; vector<pii> val[N*4]; pii arr[N]; int len,lg[N*4]; void add(int id,int pos,int len) { for (int i=pos;i<=len;i+=(i&-i)) --bit[id][i]; } int get(int id,int x,int len) { int res=0,pos=0; for (int i=(1<<lg[id]);i;i>>=1) if ((pos | i)<=len && val[id][(pos | i) - 1].fi<=x) pos|=i,res+=bit[id][pos]; return res; } int lw(int id,int x) { int sum=0,res=0,len=val[id].size(); for (int i=(1<<lg[id]);i;i>>=1) if ((res | i)<=len && sum+bit[id][res | i]<=x) res|=i,sum+=bit[id][res]; return res+1; } void build(int id,int l,int r) { if (l==r) { val[id].eb(arr[l]); bit[id].resize(2,1); pre[id].eb(-1); nex[id].eb(2); pos_in[l].eb(0); return; } int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); val[id].resize(val[id*2].size()+val[id*2+1].size()); merge(all(val[id*2]),all(val[id*2+1]),val[id].begin()); int len=val[id].size(); pre[id].resize(len); nex[id].resize(len); for (int i=0;i<len;i++) pre[id][i]=i-1,nex[id][i]=i+1,pos_in[val[id][i].se].eb(i); bit[id].resize(val[id].size()+1,0); for (int i=1;i<=len;i++) bit[id][i]=(i&-i); while (len>1) len>>=1,lg[id]++; } void input(pii ar[],int siz) { len=siz; for (int i=1;i<=len;i++) arr[i]=ar[i]; for (int i=1;i<=len*4;i++) pos_in[i].reserve(20); build(1,1,len); } void update(int id,int l,int r,int v,int layer) { int pos=pos_in[v][layer]; add(id,pos+1,val[id].size()); if (pre[id][pos]>-1) nex[id][pre[id][pos]]=nex[id][pos]; if (nex[id][pos]<(int)val[id].size()) pre[id][nex[id][pos]]=pre[id][pos]; if (l==r) return; int mid=(l+r)/2; if (v<=mid) update(id*2,l,mid,v,layer-1); else update(id*2+1,mid+1,r,v,layer-1); } void searc(int id,int l,int r,int u,int v,int y1,int y2,int i) { if (l>v || r<u) return; if (u<=l && r<=v) { int pos=lw(id,get(id,y1-1,val[id].size()))-1; if (pos>=(int)val[id].size()) return; while (pos<(int)val[id].size() && val[id][pos].fi<=y2) { int x=val[id][pos].se; pos=nex[id][pos]; if (intersect(i,X[x].se)) { ans[a[X[x].se].id]=a[i].id; update(1,1,n,x,pos_in[x].size()-1); } } return; } int mid=(l+r)/2; searc(id*2,l,mid,u,v,y1,y2,i); searc(id*2+1,mid+1,r,u,v,y1,y2,i); } void find_pot(int u,int v,int y1,int y2,int i) { if (u<=v) searc(1,1,n,u,v,y1,y2,i); } } seg; void read() { cin>>n; for (int i=1;i<=n;i++) cin>>a[i].x>>a[i].y>>a[i].r,a[i].id=i; } bool cmp(circle &obj1, circle &obj2) { return (obj1.r>obj2.r) || ((obj1.r==obj2.r) && (obj1.id<obj2.id));} void process() { sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++) X[i]=mp(a[i].x,i); sort(X+1,X+n+1); for (int i=1;i<=n;i++) Y[i]=mp(a[X[i].se].y,i); seg.input(Y,n); for (int i=1;i<=n;i++) if (ans[a[i].id]==0) { int x1=max(-inf,(ll)a[i].x-a[i].r*2),x2=min(inf,(ll)a[i].x+a[i].r*2); int y1=max(-inf,(ll)a[i].y-a[i].r*2),y2=min(inf,(ll)a[i].y+a[i].r*2); int u=lower_bound(X+1,X+n+1,mp(x1,0))-X; int v=upper_bound(X+1,X+n+1,mp(x2,n+2))-X-1; seg.find_pot(u,v,y1,y2,i); } for (int i=1;i<=n;i++) cout<<ans[i]<<" "; } int main() { //freopen("ss.inp","r",stdin); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); read(); process(); 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...