zoukankan      html  css  js  c++  java
  • BZOJ 4140 凸包+二进制分组

    思路:

    $(x_0-x)^2+(y_0-y)^2<=x^2+y^2$

    $y>=(-x_0/y_0)x+(x_0^2+y_0^2)/2y0$

    这显然就是凸包了

    以一个斜率不断向下(上)走  找到第一个接触到的点

    离线可以用cdq分治一发 他左边的判一判是不是都符合在圆内

    这不能离线就很难搞了

    感觉自己代码能力捉鸡   写棵splay估计要调死 

    强烈安利二进制分组做法

    非常强

    在log个凸包上 二分一下斜率 判一判 就好了

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=500050;
    const double pi=acos(-1),eps=1e-10;
    int n,op,flg,tot,num,top,rec,size[55];
    struct Point{double x,y;Point(double X=0,double Y=0):x(X),y(Y){}}jy,lst[N],q[N];
    Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
    double operator*(Point a,Point b){return a.x*b.y-a.y*b.x;}
    bool operator<(Point a,Point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    bool cmp(Point a,Point b){return (a-lst[1])*(b-lst[1])>-eps;}
    vector<Point>vec[30];vector<double>ang[30];
    void Tubao(){
        for(int i=2;i<=num;i++)if(lst[i]<lst[1])swap(lst[1],lst[i]);
        sort(lst+2,lst+1+num,cmp),top=0;
        for(int i=1;i<=num;i++){
            while(top>1&&(lst[i]-q[top])*(q[top]-q[top-1])>-eps)top--;
            q[++top]=lst[i];
        }
    }
    double A(double x){return x<=-pi/2?x+2*pi:x;}
    void insert(Point p){
        vec[++tot].push_back(p),size[tot]=1,lst[num=1]=p;
        while(tot>1&&size[tot]==size[tot-1]){
            for(int i=0;i<vec[tot-1].size();i++)lst[++num]=vec[tot-1][i];
            size[tot-1]+=size[tot],size[tot]=0,vec[tot].clear(),ang[tot].clear(),tot--;
        }
        Tubao(),vec[tot].clear(),ang[tot].clear();
        if(top>1){
            for(int i=1;i<top;i++)vec[tot].push_back(q[i]),ang[tot].push_back(A(atan2(q[i+1].y-q[i].y,q[i+1].x-q[i].x)));
            vec[tot].push_back(q[top]),ang[tot].push_back(A(atan2(q[1].y-q[top].y,q[1].x-q[top].x)));
        }
        else vec[tot].push_back(q[1]);
    }
    bool query(){
        double angle;
        angle=jy.y>0?A(atan2(-jy.x,jy.y)):A(atan2(jy.x,-jy.y));
        for(int i=1;i<=tot;i++){
            op=vec[i].size()==1?0:lower_bound(ang[i].begin(),ang[i].end(),angle)-ang[i].begin();
            if(2*jy.x*vec[i][op].x+2*jy.y*vec[i][op].y-jy.x*jy.x-jy.y*jy.y<eps)return 0;
        }return 1;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%lf%lf",&op,&jy.x,&jy.y),jy.x+=rec,jy.y+=rec;
            if(op==0)flg=1,insert(jy);
            else flg&&query()?(puts("Yes"),rec++):puts("No");
        }
    }
  • 相关阅读:
    github加速
    aardio类的例子
    aardio调用dll
    荔枝派nano例子
    我的书单
    架构设计之熔断设计
    【leetcode】两数之和
    K-近邻算法(KNN)
    CLion之C++框架篇-优化开源框架,引入curl,实现get方式获取资源(四)
    CLion之C++框架篇-优化框架,引入boost(三)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6908810.html
Copyright © 2011-2022 走看看