[BZOJ2732][HNOI2012] Archery (two points + half plane intersection)

Keywords: less

Title:

I'm a hyperlink

Explanation:

This level contains the previous features, which are obviously dichotomous
If you draw persimmons randomly, you will have Y1 < = AX2 + B x < = Y2, and x,y1,y2 are all known. Isn't this a straight line about a,b, half plane intersection?
The data range is only half plane intersection energy of nlogn. The total complexity O(nlog2n)
When selecting a point on a straight line, be careful not to select the intersection point with the coordinate axis, because there is no way to express a straight line passing through the origin, then choose any one=
Because the straight line here doesn't necessarily yield anything, we have to add a huge box outside. Note that the box here is a,b, a must be less than 0, b must be greater than 0, and the axis of symmetry is on the right.
Also, when judging the right side of the line, you must add '=', and consider carefully when selecting eps and INF. INF cannot be too large, eps cannot be too large or too small = =, and double can also be replaced.
Overloading operators in structures is very fast.

code:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const long double INF=1e11;//
const int N=200050;
const long double eps=1e-12;//
const long double X1=3.0;
const long double X2=-1.0;
int dcmp(long double x)
{
    if (x>=-eps && x<=eps) return 0;
    return (x>0)?1:-1;
};
struct po
{
    long double x,y;
    po (long double X=0,long double Y=0){x=X;y=Y;}
}p[N],d[N];
struct line
{
    po x,v;long double ang;
    line (po X=po(0,0),po V=po(0,0)){x=X; v=V; ang=atan2(v.y,v.x);}
    bool operator <(line a)const {return ang<a.ang;}
}L[N],q[N],s[N];int head,tail;
po operator -(po x,po y){return po(x.x-y.x,x.y-y.y);}
po operator +(po x,po y){return po(x.x+y.x,x.y+y.y);}
po operator *(po x,long double y){return po(x.x*y,x.y*y);}
long double cj(po x,po y){return x.x*y.y-x.y*y.x;}
po jd(line a,line b)
{
    po u=a.x-b.x;
    long double t=cj(b.v,u)/cj(a.v,b.v);
    return a.x+a.v*t;
}
bool Onleft(line x,po y){return dcmp(cj(x.v,y-x.x))>=0;} //
bool halfp(int n)
{
    for (int i=1;i<=n;i++) L[i]=s[i];
    sort(L+1,L+n+1);
    head=tail=1; q[1]=L[1];
    for (int i=2;i<=n;i++)
    {
        while (head<tail && !Onleft(L[i],p[tail-1])) tail--;
        while (head<tail && !Onleft(L[i],p[head])) head++;
        q[++tail]=L[i];
        if (dcmp(cj(q[tail].v,q[tail-1].v))==0)
        {
            tail--;
            if (Onleft(q[tail],L[i].x)) q[tail]=L[i];
        }
        if (head<tail) p[tail-1]=jd(q[tail],q[tail-1]);
    }
    while (head<tail && !Onleft(q[head],p[tail-1])) tail--;
    if (tail-head<=1) return 0;return 1;//
}
int read()
{
    char c=getchar();int x=0,f=1;
    while (c<'0' || c>'9'){if (c=='-') f=-1;c=getchar();}
    while (c>='0' && c<='9') x=x*10+c-'0',c=getchar();
    return f*x;
}
int main()
{
    long double x,y1,y2;int n,id=0;
    n=read();
    s[++id]=line(po(0,0),po(0,INF));
    s[++id]=line(po(0,INF),po(-INF,0));
    s[++id]=line(po(-INF,INF),po(0,-INF));
    s[++id]=line(po(-INF,0),po(INF,0));
    for (int i=1;i<=n;i++)
    {
        x=read(); y1=read(); y2=read();
        po a=po(X1,(y1-x*x*X1)/x);
        po b=po(X2,(y1-x*x*X2)/x);
        s[++id]=line(b,a-b);
        a=po(X1,(y2-x*x*X1)/x);
        b=po(X2,(y2-x*x*X2)/x);
        s[++id]=line(a,b-a);
    }
    int l=1,r=n,ans;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if (halfp(mid*2+4)) ans=mid,l=mid+1;
        else r=mid-1;
    }
    printf("%d",ans);
}

Posted by micmania1 on Sat, 02 May 2020 11:00:53 -0700