CF70D Professor's task

CF70D Professor's task

题意

两种操作:
1.往点集S中添加一个点(x,y);
2.询问(x,y)是否在点集S的凸包中. 数据保证至少有一个2操作, 保证刚开始会给出三个1操作, 且这三个操作中的点不共线.
操作数不超过\({10}^{5}\)

题解

动态凸包的板子题。。具体康代码吧。。

\(Code\)

#include <bits/stdc++.h>
#define LL long long
#define LD long double
using namespace std;
const int N=1e5+10;
const LD eps=1e-10;
const LL INF=1e18;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void print(LL x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

struct P{
    LL x,y;LD ang;
    P(LL xx=0,LL yy=0){x=xx;y=yy;ang=atan2(y,x);}
}p[N],O;

P operator + (P x,P y){return P(x.x+y.x,x.y+y.y);}
P operator - (P x,P y){return P(x.x-y.x,x.y-y.y);}
LL cha(P x,P y){return x.x*y.y-x.y*y.x;} 
LL len(P x){return x.x*x.x+x.y*x.y;}

bool operator < (P x,P y){
    if(fabs(x.ang-y.ang)<eps) return len(x)<len(y);
    return x.ang<y.ang;
}

set<P> S;

#define ST set<P>::iterator 

ST get_pre(ST it){
    if(it==S.begin()) it=S.end();--it;
    return it;
}
ST get_suf(ST it){
    ++it;if(it==S.end())it=S.begin();
    return it;
}

ST it,pre,suf,tmp;

P pr,su,t; 

void ins(P x){
    it=S.lower_bound(x);
    if(it==S.end()) it=S.begin();
    pre=get_pre(it);
    pr=(*pre);
    su=(*it);
    if(cha(x-pr,su-pr)<=0) return;
    S.insert(x);tmp=get_pre(pre);t=(*tmp);
    while(cha(pr-t,x-t)<=0){
          S.erase(pre);
              pre=tmp;tmp=get_pre(pre);
              pr=(*pre);t=(*tmp);
    }
    tmp=get_suf(it);t=(*tmp);
    while(cha(x-t,su-t)<=0){
              S.erase(it);
              it=tmp;tmp=get_suf(it);
              su=(*it);t=(*tmp);
        }
        return;
}

bool init(P x){
    it=S.lower_bound(x);
    if(it==S.end()) it=S.begin();
    pre=get_pre(it);
    pr=(*pre);
    su=(*it);
    if(cha(x-pr,su-pr)<=0) return 1;
    else return 0;
}

int main(){
    int op;LL x,y;
    int T;scanf("%d",&T);T-=3;
    for(int i=1;i<=3;++i) scanf("%d%I64d%I64d",&op,&p[i].x,&p[i].y);
    O=p[1]+p[2]+p[3];
    p[1].x*=3;p[1].y*=3;p[1]=p[1]-O;S.insert(p[1]);
    p[2].x*=3;p[2].y*=3;p[2]=p[2]-O;S.insert(p[2]);
    p[3].x*=3;p[3].y*=3;p[3]=p[3]-O;S.insert(p[3]);
//    it=S.begin();p[1]=(*it);cout<<p[1].x<<" "<<p[1].y<<" "<<p[1].ang<<" "<<atan2(p[1].y,p[1].x)<<endl;
//    ++it;p[1]=(*it);cout<<p[1].x<<" "<<p[1].y<<" "<<p[1].ang<<" "<<atan2(p[1].y,p[1].x)<<endl;
//    ++it;p[1]=(*it);cout<<p[1].x<<" "<<p[1].y<<" "<<p[1].ang<<" "<<atan2(p[1].y,p[1].x)<<endl;
    while(T--){
        scanf("%d%I64d%I64d",&op,&x,&y);x*=3;y*=3;
        if(op==1) ins(P(x,y)-O);
        else init(P(x,y)-O)?puts("YES"):puts("NO");
    }
        return 0;
}


posted @ 2020-10-18 22:41  Iscream-2001  阅读(98)  评论(0编辑  收藏  举报
/* */ /* */