제출 #272721

#제출 시각아이디문제언어결과실행 시간메모리
272721MKopchev원 고르기 (APIO18_circle_selection)C++14
7 / 100
2774 ms380120 KiB
#include<bits/stdc++.h> using namespace std; const int nmax=3e5+42,inf=1e9+42,MX=(1<<20)+42; struct circle { int x,y,r,id; }; int n; circle inp[nmax],sorted_inp[nmax],other_sorted[nmax]; bool touch(circle a,circle b) { long long d=1LL*(a.x-b.x)*(a.x-b.x)+1LL*(a.y-b.y)*(a.y-b.y); long long mx=a.r+b.r; mx=mx*mx; return d<=mx; } bool cmp(circle a,circle b) { if(a.r!=b.r)return a.r>b.r; return a.id<b.id; } bool cmp_y(circle a,circle b) { if(a.y!=b.y)return a.y<b.y; return a.id<b.id; } int outp[nmax]; vector< pair<int/*y*/,int/*id*/> > nodes[MX]; vector<int> prv[MX]; vector<int> nxt[MX]; vector<int> tree[MX]; void update(int node,int l,int r,int pos,circle cur) { //cout<<node<<" -> "<<cur.y<<" "<<cur.id<<endl; nodes[node].push_back({cur.y,cur.id}); if(l==r)return; int av=(l+r)/2; if(pos<=av)update(node*2,l,av,pos,cur); else update(node*2+1,av+1,r,pos,cur); } void build(int where,int node,int l,int r) { while(tree[where].size()<=node)tree[where].push_back(0); tree[where][node]=r-l+1; if(l==r)return; int av=(l+r)/2; build(where,node*2,l,av); build(where,node*2+1,av+1,r); } void sub_tree(int where,int node,int l,int r,int pos) { while(l!=r) { tree[where][node]--; if(l==r)return; int av=(l+r)/2; if(pos<=av)node=node*2,r=av; else node=node*2+1,l=av+1; } } int query(int where,int node,int l,int r,int lq,int rq) { if(tree[where][node]==0)return -1; if(l==r)return l; int av=(l+r)/2; if(lq<=av) { int mem=query(where,node*2,l,av,lq,min(av,rq)); if(mem!=-1)return mem; } if(av<rq) { int mem=query(where,node*2+1,av+1,r,max(av+1,lq),rq); if(mem!=-1)return mem; } return -1; } int find_first(int where,int start) { return query(where,1,0,nodes[where].size()-1,start,nodes[where].size()-1); } int pick(int a,int b) { long long sum=a; sum=sum+b; if(inf<sum)sum=inf; if(-inf>sum)sum=-inf; return sum; } void match(int node,int l,int r,int lq,int rq,circle cur) { if(tree[node].size()==0)return; if(tree[node][1]==0)return; if(l==lq&&r==rq) { int y1=pick(cur.y,-2*cur.r); int y2=pick(cur.y,2*cur.r); int start=lower_bound(nodes[node].begin(),nodes[node].end(),make_pair(y1,0))-nodes[node].begin(); if(start==nodes[node].size())return; start=find_first(node,start); /* cout<<"circle "<<l<<" "<<r<<" "<<cur.id<<endl; for(auto k:nodes[node]) cout<<k.first<<" "<<k.second<<"\t";cout<<endl; cout<<"y1= "<<y1<<" y2= "<<y2<<" start= "<<start<<endl; */ if(start==-1)return; vector<int> to_pop={}; while(start<nodes[node].size()&&nodes[node][start].first<=y2) { //cout<<"start= "<<start<<" "<<nodes[node][start].second<<" "<<inp[nodes[node][start].second].x<<" "<<inp[nodes[node][start].second].y<<" "<<inp[nodes[node][start].second].r<<endl; if(outp[nodes[node][start].second]==0&&touch(inp[nodes[node][start].second],cur)) { //cout<<"touch "<<nodes[node][start].second<<" "<<cur.id<<" "<<endl; outp[nodes[node][start].second]=cur.id; } if(outp[nodes[node][start].second])to_pop.push_back(start); start=nxt[node][start]; } for(auto k:to_pop) { if(0<=prv[node][k]) { nxt[node][prv[node][k]]=nxt[node][k]; } if(nxt[node][k]<nodes[node].size()) { prv[node][nxt[node][k]]=prv[node][k]; } sub_tree(node,1,0,nodes[node].size()-1,k); } return; } int av=(l+r)/2; if(lq<=av)match(node*2,l,av,lq,min(av,rq),cur); if(av<rq)match(node*2+1,av+1,r,max(av+1,lq),rq,cur); } int help_x[nmax]; void push(int which) { outp[sorted_inp[which].id]=sorted_inp[which].id; int x1=pick(sorted_inp[which].x,-2*sorted_inp[which].r); int x2=pick(sorted_inp[which].x,+2*sorted_inp[which].r); int le=lower_bound(help_x+1,help_x+n+1,x1)-help_x; int ri=upper_bound(help_x+1,help_x+n+1,x2)-help_x; ri--; //cout<<"le= "<<le<<" ri= "<<ri<<endl; if(le>ri)return; match(1,1,n,le,ri,sorted_inp[which]); } signed main() { scanf("%i",&n); for(int i=1;i<=n;i++) { scanf("%i%i%i",&inp[i].x,&inp[i].y,&inp[i].r); inp[i].id=i; } for(int i=1;i<=n;i++)sorted_inp[i]=inp[i],other_sorted[i]=inp[i]; sort(other_sorted+1,other_sorted+n+1,cmp_y); sort(sorted_inp+1,sorted_inp+n+1,cmp); for(int i=1;i<=n;i++)help_x[i]=sorted_inp[i].x; sort(help_x+1,help_x+n+1); for(int i=1;i<=n;i++) { int pos=lower_bound(help_x+1,help_x+n+1,other_sorted[i].x)-help_x; update(1,1,n,pos,other_sorted[i]); } for(int i=1;i<MX;i++) if(nodes[i].size()) { for(int j=0;j<nodes[i].size();j++) { prv[i].push_back(j-1); nxt[i].push_back(j+1); } build(i,1,0,nodes[i].size()-1); } for(int i=1;i<=n;i++) if(outp[sorted_inp[i].id]==0) push(i); for(int i=1;i<=n;i++)printf("%i ",outp[i]);printf("\n"); return 0; }

컴파일 시 표준 에러 (stderr) 메시지

circle_selection.cpp: In function 'void build(int, int, int, int)':
circle_selection.cpp:56:29: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   56 |     while(tree[where].size()<=node)tree[where].push_back(0);
      |           ~~~~~~~~~~~~~~~~~~^~~~~~
circle_selection.cpp: In function 'void match(int, int, int, int, int, circle)':
circle_selection.cpp:128:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  128 |         if(start==nodes[node].size())return;
      |            ~~~~~^~~~~~~~~~~~~~~~~~~~
circle_selection.cpp:143:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  143 |         while(start<nodes[node].size()&&nodes[node][start].first<=y2)
      |               ~~~~~^~~~~~~~~~~~~~~~~~~
circle_selection.cpp:165:28: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type' {aka 'int'} and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  165 |             if(nxt[node][k]<nodes[node].size())
circle_selection.cpp: In function 'int main()':
circle_selection.cpp:230:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  230 |             for(int j=0;j<nodes[i].size();j++)
      |                         ~^~~~~~~~~~~~~~~~
circle_selection.cpp:242:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  242 |     for(int i=1;i<=n;i++)printf("%i ",outp[i]);printf("\n");
      |     ^~~
circle_selection.cpp:242:48: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  242 |     for(int i=1;i<=n;i++)printf("%i ",outp[i]);printf("\n");
      |                                                ^~~~~~
circle_selection.cpp:203:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  203 |     scanf("%i",&n);
      |     ~~~~~^~~~~~~~~
circle_selection.cpp:206:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  206 |         scanf("%i%i%i",&inp[i].x,&inp[i].y,&inp[i].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...