https://www.luogu.org/problemnew/show/P2928
analysis
A very interesting question thinking
Because all the points are in motion, do not we change the relative motion
Set bessie (0,0), do not exercise at home, the killers of parameters compared (x-bx, y-by, vx-vbx, vy-vby)
So the subject becomes a killer when seeking to enter or tangent to r is the radius of the circle centered at the origin
You can have the equation:
$ R ^ 2 = (x + tvx) ^ 2 + (y + tvy) ^ 2 $
Into a conventional style
$(vx^2+vy^2)t^2+2*(x\cdot vx+y\cdot vy)t+x^2+y^2-r^2=0$
Then solve the equation, the two solutions into the memory array, discrete ordering
Take a segment tree can be a total answer
note:
1, if there is no point in the relative motion of the motion, determines whether to have been within a circle or
2, to sentence no solution, the solution is less than 0, etc.
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef double db; const int N=5e4+10; struct Cow { db x,y,vx,vy; void In() {scanf("%lf%lf%lf%lf",&x,&y,&vx,&vy);} Cow operator - (Cow &b) { return (Cow){x-b.x,y-b.y,vx-b.vx,vy-b.vy}; } }t,a[N]; int s[N<<3],lz[N<<3],rt=1; int cnt; db p[2*N],q[N][2]; int n,r,ans,e; void Calc(int x) { db A=pow(a[x].vx,2)+pow(a[x].vy,2),B=2*a[x].x*a[x].vx+2*a[x].y*a[x].vy, C=pow(a[x].x,2)+pow(a[x].y,2)-pow(r,2); db delta=pow(B,2)-4.0*A*C; if (delta<0.0) return; db d_root=sqrt(delta); db x1=(-1.0*B-d_root)/(2.0*A),x2=(-1.0*B+d_root)/(2.0*A); if (x1<0.0) x1=0;if (x2<=0.0) return; p[++cnt]=x1,1;p[++cnt]=x2,-1; q[cnt>>1][0]=x1;q[cnt>>1][1]=x2; } void Pushdown(int x) { s[x<<1]+=lz[x];lz[x<<1]+=lz[x]; s[(x<<1)+1]+=lz[x];lz[(x<<1)+1]+=lz[x]; lz[x]=0; } void Add(int x,int l,int r,int L,int R) { if (r<L||R<l||r<l) return; if (L<=l&&r<=R) { s[x]++;lz[x]++; return; } Pushdown(x); int mid=l+r>>1; if (L<=mid) Add(x<<1,l,mid,L,R); if (mid<R) Add((x<<1)+1,mid+1,r,L,R); s[x]=max(s[x<<1],s[(x<<1)+1]); } int main() { scanf("%d%d",&n,&r); t.In(); for (int i=1;i<=n;i++) a[i].In(),a[i]=a[i]-t; for (int i=1;i<=n;i++) if (a[i].vx!=0||a[i].vy!=0) Calc(i); else if (pow(a[i].x,2)+pow(a[i].y,2)<=pow(r,2)) e++; sort(p+1,p+cnt+1); for (int i=1;i<=(cnt>>1);i++) { int l=lower_bound(p+1,p+cnt+1,q[i][0])-p,r=lower_bound(p+1,p+cnt+1,q[i][1])-p; Add(rt,1,cnt,l,r); } ans=s[rt]+e; printf("%d",ans); }