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


原文地址:https://www.cnblogs.com/Yuigahama/p/13837633.html