Submission #230856

#TimeUsernameProblemLanguageResultExecution timeMemory
230856frodakcinRelay (COI16_relay)C++11
100 / 100
143 ms7928 KiB
#include <cstdio> #include <cassert> using ll = long long; struct vec { public: ll x, y; vec(ll x=0, ll y=0) : x(x), y(y) {} void in(){scanf("%lld%lld", &x, &y);} ll operator / (vec o) const {return x*o.y-o.x*y;} ll operator * (vec o) const {return x*o.x+y*o.y;} vec& operator += (vec o) {return x+=o.x, y+=o.y, *this;} vec& operator -= (vec o) {return x-=o.x, y-=o.y, *this;} friend vec operator + (vec a, vec b) {return a += b;} friend vec operator - (vec a, vec b) {return a -= b;} }; const int MN = 2e5 + 10; int N, M, low[MN], high[MN], ans; bool mayday[MN]; vec a[MN], b[MN]; struct ray { public: vec s, d; }; ray bot, top; int main(void) { scanf("%d", &N); for(int i=0;i<N;++i) a[i].in(); scanf("%d", &M); for(int i=0;i<M;++i) b[i].in(), b[i+M]=b[i];//for convenience for(int i=0,l,r,m,u,v,z;i<N;++i) { vec x=a[i]; //printf("INFO FOR (id: %d), (%lld, %lld) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", i+1, x.x, x.y); z=0; vec d=b[z]-x; if(d/(b[1]-b[0]) == 0) d=b[++z]-x; if(d/(b[z+1]-b[z]) > 0) { l=z,r=M+z; for(;r-l>1;) { m=l+(r-l)/2; if(d/(b[m]-b[z]) < 0) r=m; else l=m; } u=l; } else u=z; u%=M; assert((b[u]-x)/(b[u+1]-x) <= 0); //b[u] is on the same side as a[i] d=b[u]-x; l=u,r=u+M; for(;r-l>1;) { m=l+(r-l)/2; if(d/(b[m]-b[u]) > 0) r=m; else l=m; } v=l%M; //printf("VALS: %d %d\n", u, v); assert((b[v]-x)/(b[v+1]-x) >= 0); //u<->v cut the convex hull //u is on closer side //lower hull: v...u { l=v,r=u; if(r<l)r+=M; --l; for(;r-l>1;) { m=l+(r-l)/2; if((b[m]-x)/(b[m+1]-b[m])>0) l=m; else r=m; } low[i] = r%M; } //upper hull: u...v { l=u,r=v; if(r<l) r+=M; --l; for(;r-l>1;) { m=l+(r-l)/2; if((b[m]-x)/(b[m+1]-b[m])<=0) l=m; else r=m; } high[i] = r%M; } //printf("\tLOW: (%lld, %lld)\n", b[low[i]].x, b[low[i]].y); //printf("\tHIGH: (%lld, %lld)\n", b[high[i]].x, b[high[i]].y); //printf("\n"); assert((b[low[i]]-x)/(b[low[i]+1]-b[low[i]]) <= 0); assert((b[low[i]+M-1]-x)/(b[low[i]]-b[low[i]+M-1]) > 0); assert((b[high[i]]-x)/(b[high[i]+1]-b[high[i]]) > 0); assert((b[high[i]+M-1]-x)/(b[high[i]]-b[high[i]+M-1]) <= 0); } bot = {b[low[0]], b[low[0]]-a[0]}; top = {b[high[0]], b[high[0]]-a[0]}; vec bot0 = b[low[0]]-a[0]; vec top0 = b[high[0]]-a[0]; for(int i=1;i<N;++i) { if(bot.d/(a[i]-bot.s)>=0 || top.d/(a[i]-top.s)<=0) mayday[i] = 1; else if((a[i]-top.s)/(a[i]-bot.s) >= 0) mayday[i] = 1; } for(int i=1;i<N;++i) if(mayday[i]) { //printf("MAYDAY: (id: %d), (%lld, %lld)\n", i+1, a[i].x, a[i].y); ray bot2 = {b[low[i]], b[low[i]]-a[i]}; ray top2 = {b[high[i]], b[high[i]]-a[i]}; if(bot0/bot2.d <= 0 && bot.d/bot2.d < 0) bot = bot2; if(top0/top2.d >= 0 && top.d/top2.d > 0) top = top2; } if((top.s-a[0])/(bot.s-a[0]) <= 0) return printf("%d\n", N-1), 0; for(int i=1;i<N;++i) { bool relay=0; if(bot.d/(a[i]-bot.s)>=0 || top.d/(a[i]-top.s)<=0) relay = 1; else if((a[i]-top.s)/(a[i]-bot.s) >= 0) relay = 1; if(relay) { ++ans; //printf("RELAY: (id: %d), (%lld, %lld)\n", i+1, a[i].x, a[i].y); } } printf("%d\n", ans); return 0; }

Compilation message (stderr)

relay.cpp: In function 'int main()':
relay.cpp:33:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &N);
  ~~~~~^~~~~~~~~~
relay.cpp:36:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &M);
  ~~~~~^~~~~~~~~~
relay.cpp: In member function 'void vec::in()':
relay.cpp:10:17: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  void in(){scanf("%lld%lld", &x, &y);}
            ~~~~~^~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...