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");
    }
}

 

posted @ 2017-05-26 15:35  SiriusRen  阅读(432)  评论(0编辑  收藏  举报