[Tree line] [mathematical] [discrete] luogu P2928 cattle thugs

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);
}
View Code

 

Guess you like

Origin www.cnblogs.com/mastervan/p/11123382.html