【BZOJ2961】共点圆(圆的反演)(半平面交)(CDQ分治)

传送门


用了Lambda表达式,需要开C++11,只能在darkbzoj上交。

题解:

由于所有圆都过原点,直接反演后将所有圆交的区域表示为半平面交,然后上CDQ分治判断就行了。


代码:

#include
#define ll long long
#define re register
#define db double
#define cs const

namespace IO{
     
	inline char gc(){
     
		static cs int Rlen=1<<22|1;static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}template<typename T>T get_integer(){
     
		char c;bool f=false;while(!isdigit(c=gc()))f=c=='-';T num=c^48;
		while(isdigit(c=gc()))num=((num+(num<<2))<<1)+(c^48);return f?-num:num;
	}inline int gi(){
     return get_integer<int>();}
	template<typename T>T get_float(){
     
		char c;bool f=false;while(!isdigit(c=gc()))f=c=='-';T x=c^48;
		while(isdigit(c=gc()))x=(x*10)+(c^48);if(c!='.')return f?-x:x;
		db y=1.;while(isdigit(c=gc()))x+=(y/=10)*(c^48);return f?-x:x;
	}inline db gd(){
     return get_float<db>();}
}using namespace IO;

using std::cerr;
using std::cout;

cs db eps=1e-8,R=1e4;
inline db sqr(db x){
     return x*x;}
inline int sign(db x){
     return x<-eps?-1:(x>eps?1:0);}
struct Pnt{
     
	db x,y;Pnt(){
     }Pnt(db _x,db _y):x(_x),y(_y){
     }
	friend Pnt operator+(cs Pnt &a,cs Pnt &b){
     return Pnt(a.x+b.x,a.y+b.y);}
	friend Pnt operator-(cs Pnt &a,cs Pnt &b){
     return Pnt(a.x-b.x,a.y-b.y);}
	friend Pnt operator*(cs Pnt &a,db b){
     return Pnt(a.x*b,a.y*b);}
	friend Pnt operator/(cs Pnt &a,db b){
     return Pnt(a.x/b,a.y/b);}
	friend db operator*(cs Pnt &a,cs Pnt &b){
     return a.x*b.y-a.y*b.x;}
	friend db dot(cs Pnt &a,cs Pnt &b){
     return a.x*b.x+a.y*b.y;}
	inline db len()cs{
     return sqrt(x*x+y*y);}
	inline db ang()cs{
     return atan2(y,x);}
	inline Pnt rot()cs{
     return Pnt(y,-x);}
};

inline db crs(cs Pnt &a,cs Pnt &b,cs Pnt &c){
     
	return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}

struct Line{
     
	Pnt s,t;Line(){
     }Line(cs Pnt &_s,cs Pnt &_t):s(_s),t(_t){
     }
	Pnt dir()cs{
     return t-s;}
};

inline Pnt inter(cs Line &a,cs Line &b){
     
	return a.s+(a.dir())*(crs(b.s,b.t,a.s)/((a.dir())*(b.dir())));
}

inline Line inv(cs Pnt &O){
     
	Pnt s=O*sqr(R/O.len());return Line(s,s+O.rot());
}
inline Pnt Inv(cs Pnt &O){
     return O*sqr(R/O.len());}

cs int N=5e5+7;

int n;int typ[N];
Pnt p[N];bool ans[N];

void solve(int l,int r,std::vector<Line> &S,std::vector<int> &P){
     
	if(l==r){
     
		if(typ[l]==0)S.push_back(inv(p[l]*2));
		else if(ans[l])p[l]=Inv(p[l]),P.push_back(l);return;
	}int mid=(l+r)>>1;
	std::vector<Line> sl,sr;std::vector<int> pl,pr;
	solve(l,mid,sl,pl),solve(mid+1,r,sr,pr);
	if(sl.size()){
     unsigned int h=0;
		for(int re i:pr){
     
			while(h+1<sl.size()&&p[i].x>=inter(sl[h],sl[h+1]).x)++h;
			ans[i]&=sign(crs(sl[h].s,sl[h].t,p[i]))>=0;
		}
	}
	
	auto cmp_Line=[](cs Line &a,cs Line &b)->bool{
     
		return sign(a.dir()*b.dir())?sign(a.dir()*b.dir())>0:sign(crs(b.s,b.t,a.t))<0;
	};
	auto judge=[](cs Pnt &a,cs Line &b)->bool{
     return sign(b.dir()*(a-b.s))>=0;};
	auto ins=[&](cs Line &it)->void{
     
		while(S.size()>1&&judge(inter(S[S.size()-2],it),S.back()))S.pop_back();
		while(S.size()&&!sign(it.dir()*S.back().dir()))S.pop_back();
		S.push_back(it);
	};unsigned int hl=0,hr=0;
	while(hl<sl.size()&&hr<sr.size())ins(cmp_Line(sl[hl],sr[hr])?sl[hl++]:sr[hr++]);
	while(hl<sl.size())ins(sl[hl++]);while(hr<sr.size())ins(sr[hr++]);
	
	auto cmp_x=[](int i,int j)->bool{
     return p[i].x<p[j].x;};
	auto push=[&](int i)->void{
     if(ans[i])P.push_back(i);};hl=hr=0;
	while(hl<pl.size()&&hr<pr.size())push(cmp_x(pl[hl],pr[hr])?pl[hl++]:pr[hr++]);
	while(hl<pl.size())push(pl[hl++]);while(hr<pr.size())push(pr[hr++]);
}

void Main(){
     n=gi();bool exi=false;
	for(int re i=1;i<=n;++i){
     
		typ[i]=gi();p[i].x=gd(),p[i].y=gd();
		ans[i]=exi;if(typ[i]==0)exi=true;
	}std::vector<Line> S;std::vector<int> P;solve(1,n,S,P);
	for(int re i=1;i<=n;++i)if(typ[i]==1)puts(ans[i]?"Yes":"No");
}

inline void file(){
     
#ifdef zxyoi
	freopen("cir.in","r",stdin);
	freopen("cir.out","w",stdout);
#endif
}
signed main(){
     file();Main();return 0;}

你可能感兴趣的:(_____分治_____,半平面交)