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