[CF70D]Professor's task

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF70D]Professor's task相关的知识,希望对你有一定的参考价值。

题意:给三个点和一些操作,可以加点或询问某点是否在当前点集的凸包内

如果写水平序凸包,要维护上下凸壳,挺麻烦

注意到题目给了初始的三个点,所以直接在这个三角形里面随便找一个点(我选的是重心)作为原点,然后做极角序凸包就可以了

#include<stdio.h>
#include<math.h>
#include<set>
using namespace std;
const double pi=3.141592653589793238462643383;
const double eps=1e-8;
double abs(double x){return x>0?x:-x;}
struct point{
	double xx,yy,ang,len;
	point(double x=0.,double y=0.){
		xx=x;
		yy=y;
		len=sqrt(x*x+y*y);
		if(abs(x)<eps)
			ang=y>eps?pi*.5:pi*-.5;
		else{
			if(x>eps)
				ang=atan(y/x);
			else
				ang=(y>eps?pi:-pi)+atan(y/x);
		}
	}
}p;
point operator-(point a,point b){
	return point(a.xx-b.xx,a.yy-b.yy);
}
double operator*(point a,point b){
	return a.xx*b.yy-a.yy*b.xx;
}
bool operator<(point a,point b){
	if(a.ang==b.ang)return a.len<b.len;
	return a.ang<b.ang;
}
set<point>s;
typedef set<point>::iterator sit;
sit it;
sit nex(sit x){
	x++;
	return x==s.end()?s.begin():x;
}
sit pre(sit x){
	if(x==s.begin())x=s.end();
	x--;
	return x;
}
int main(){
	int q,i,op,x[3],y[3];
	double ox,oy,xx,yy;
	scanf("%d",&q);
	q-=3;
	ox=oy=0;
	for(i=0;i<3;i++){
		scanf("%d%d%d",&op,x+i,y+i);
		ox+=x[i];
		oy+=y[i];
	}
	ox/=3.;
	oy/=3.;
	for(i=0;i<3;i++)s.insert(point(x[i]-ox,y[i]-oy));
	while(q--){
		scanf("%d%d%d",&op,x,y);
		xx=x[0]-ox;
		yy=y[0]-oy;
		p=point(xx,yy);
		it=s.lower_bound(p);
		if(it==s.end())it=s.begin();
		if(op==1){
			if((p-*pre(it))*(*it-p)>eps){
				s.insert(p);
				it=nex(s.find(p));
				while(s.size()>3&&(*it-p)*(*nex(it)-*it)<eps){
					s.erase(it);
					it=nex(s.find(p));
				}
				it=pre(s.find(p));
				while(s.size()>3&&(*it-*pre(it))*(p-*it)<eps){
					s.erase(it);
					it=pre(s.find(p));
				}
			}
		}else
			puts((p-*pre(it))*(*it-p)<eps?"YES":"NO");
	}
}

以上是关于[CF70D]Professor's task的主要内容,如果未能解决你的问题,请参考以下文章

[CF70D]Professor‘s task

「题解」CF620D Professor GukiZ and Two Arrays

「CF80A」Panoramix's Prediction

CF718EMatvey's Birthday BFS+动态规划

CF 1912 A NEKO's Maze Game

CF1279D Santa's Bot