zoukankan      html  css  js  c++  java
  • Luogu-3222 [HNOI2012]射箭

    几何题,二次函数,化一下式子吧

    设二次函数(y=ax^2+bx),对于一个线段((x,y1)),((x,y2)),与他相交的条件是(y1<=ax^2+bx<=y2)

    对于(ax^2+bx>=y1),可以化为变量为(a,b)的一次函数(b>=xa+frac{y1}{x}),这可以表示成(a-b)平面上的一个半平面...

    如果一些线段的半平面交不为空,就说明存在一条抛物线可以经过他们

    二分答案判断,时间复杂度(O(nlogn))

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=2e5+100;
    struct Point{
        double x,y;
        Point(double xx=0,double yy=0){
            x=xx,y=yy;
        }
    };
    struct Vector{
        double x,y;
        Vector(double xx=0,double yy=0){
            x=xx,y=yy;
        }
    };
    struct Line{
        Point p;
        Vector v;
        double ang;
        int bh;
        Line(Point a=Point(),Vector b=Vector()){
            p=a,v=b;
            ang=atan2(v.y,v.x);
        }
    }q[maxn],b[maxn],c[maxn];
    int dcmp(double x){return fabs(x)<1e-17?0:(x>0?1:-1);}
    Vector operator - (Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
    Point operator + (Point a,Vector b){return Point(a.x+b.x,a.y+b.y);}
    Vector operator * (double p,Vector a){return Vector(a.x*p,a.y*p);}
    double operator * (Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    double operator * (Point a,Point b){return a.x*b.y-a.y*b.x;}
    bool operator < (Line x,Line y){return dcmp(x.ang-y.ang)==0?(dcmp(x.v*(y.p-x.p))>0):(x.ang<y.ang);}
    Point glt(Line x,Line y){Vector v=x.p-y.p; return x.p+y.v*v/(x.v*y.v)*x.v;}
    bool onright(Line a,Line b,Line t){Point p=glt(a,b); return dcmp(t.v*(p-t.p))<0;}
    bool bpm(int x,int n,Line *b){
        int l=0,r=1,tot=0;
        for(int i=1;i<=n;i++)
            if(b[i].bh<=x){
                if(b[i].ang!=b[i-1].ang) tot++;
                c[tot]=b[i];
            }
        n=tot,q[0]=c[1],q[1]=c[2];
        for(int i=3;i<=n;i++){
            while(l<r&&onright(q[r],q[r-1],c[i])) r--;
            while(l<r&&onright(q[l],q[l+1],c[i])) l++;
            q[++r]=c[i];
        }
        while(l<r&&onright(q[r],q[r-1],q[l])) r--;
        while(l<r&&onright(q[l],q[l+1],q[r])) l++;
        return r-l>=2;
    }
    int n,m;
    double x,sy,ty;
    int main(){
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%lf%lf%lf",&x,&sy,&ty);
            b[++n]=Line(Point(0,sy/x),Vector(1,-x));
            b[n].bh=i;
            b[++n]=Line(Point(0,ty/x),Vector(-1,x));
            b[n].bh=i;
        }
        sort(b+1,b+n+1);
        int l=1,r=n+1,mid,ans;
        while(l<r){
            mid=l+r>>1;
            if(bpm(mid,n,b))
                ans=mid,l=mid+1;
            else
                r=mid;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Servlet学习总结
    Tomcat学习总结1
    第44周星期日反思
    第44周星期一Tomcat学习2
    第44周星期五忙碌文档的一天
    第44周星期六好文章摘录
    laravel 5.6接入微信第三方授权登陆的主要步骤
    laravel多表登录出现路由调用错误
    cURL error 60: SSL certificate problem...
    传说中Python最难理解的点|看这完篇就够了(装饰器)
  • 原文地址:https://www.cnblogs.com/nianheng/p/10013956.html
Copyright © 2011-2022 走看看