其实做法是跟离线一模一样的 只不过强制在线
可以使用二进制分组这个技巧
详见xhr论文
跑的比分治快是smg
一天到晚做数据结构的傻逼选手
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#define pb push_back
using namespace std;
typedef double ld;
const ld PI=acos(-1.0);
inline int sgn(ld t){
if (fabs(t)<1e-8) return 0;
return t<0?-1:1;
}
struct PP{
ld x,y;
void read() { scanf("%lf%lf",&x,&y); }
void print() { printf("%lf %lf\n",x,y); }
PP(ld x=0,ld y=0):x(x),y(y) { }
friend PP operator + (PP A,PP B){ return PP(A.x+B.x,A.y+B.y); }
friend PP operator - (PP A,PP B){ return PP(A.x-B.x,A.y-B.y); }
friend ld operator * (PP A,PP B){ return A.x*B.y-B.x*A.y; }
bool operator < (const PP &B) const{
return x==B.x?y<B.y:x<B.x;
}
};
int tot;
int size[25];
vector<PP> pt[25];
vector<ld> ang[25];
int Q;
PP lst[500005]; int pnt;
PP sta[500005]; int top;
PP O;
inline bool cmp(PP A,PP B){
return sgn((A-O)*(B-O))>0;
}
inline void Hull(){
for (int i=2;i<=pnt;i++)
if (lst[i]<lst[1])
swap(lst[i],lst[1]);
O=lst[1];
sort(lst+2,lst+pnt+1,cmp);
top=0;
for (int i=1;i<=pnt;i++){
while (top>1 && sgn((lst[i]-sta[top])*(sta[top]-sta[top-1]))>=0) top--;
sta[++top]=lst[i];
}
}
inline ld Tran(ld a){
return a<=-PI/2?a+2*PI:a;
}
inline void Ins(PP p){
pt[++tot].pb(p); size[tot]=1; pnt=0;
lst[++pnt]=p;
while (tot>1 && size[tot]==size[tot-1]){
for (int i=0;i<(int)pt[tot-1].size();i++)
lst[++pnt]=pt[tot-1][i];
size[tot-1]+=size[tot];
size[tot]=0; pt[tot].clear(); ang[tot].clear();
tot--;
}
Hull();
pt[tot].clear(),ang[tot].clear();
if (top>1){
for (int i=1;i<top;i++)
pt[tot].pb(sta[i]),ang[tot].pb(Tran(atan2(sta[i+1].y-sta[i].y,sta[i+1].x-sta[i].x)));
pt[tot].pb(sta[top]),ang[tot].pb(Tran(atan2(sta[1].y-sta[top].y,sta[1].x-sta[top].x)));
}else{
pt[tot].pb(sta[1]);
}
}
inline bool Query(PP p){
ld ag,x0=p.x,y0=p.y;
if (y0>0) ag=Tran(atan2(-x0,y0)); else ag=Tran(atan2(x0,-y0));
for (int i=1;i<=tot;i++){
int it;
// for (int j=0;j<(int)ang[i].size();j++)
// printf("%lf ",ang[i][j]);
// printf("\n");
if (pt[i].size()==1)
it=0;
else
it=lower_bound(ang[i].begin(),ang[i].end(),ag)-ang[i].begin();
// pt[i][it].print();
if (!(sgn(2*x0*pt[i][it].x+2*y0*pt[i][it].y-x0*x0-y0*y0)>=0))
return 0;
}
return 1;
}
int main(){
int order; PP p; int mask=0;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&Q);
int f=0;
while (Q--){
scanf("%d",&order); p.read();
p.x+=mask; p.y+=mask;
if (order==0)
f=1,Ins(p);
else{
if (!f) { printf("No\n"); continue; }
Query(p)?(printf("Yes\n"),mask++):printf("No\n");
}
}
return 0;
}