BZOJ2961: 共点圆
好久没发了
CDQ分治,具体做法见XHR的论文…
1 /************************************************************** 2 Problem: 2961 3 User: zhuohan123 4 Language: C++ 5 Result: Accepted 6 Time:5060 ms 7 Memory:41704 kb 8 ****************************************************************/ 9 10 #include <iostream> 11 #include <cmath> 12 #include <cstdio> 13 #include <cstring> 14 #include <algorithm> 15 using namespace std; 16 const double eps=1e-9,inf=1e12; 17 struct point 18 { 19 double x,y; 20 point(){x=y=0;} 21 point(double X,double Y){x=X,y=Y;} 22 friend bool operator<(point a,point b) 23 { 24 if(abs(a.x-b.x)<eps)return a.y+eps<b.y; 25 else return a.x+eps<b.x; 26 } 27 }; 28 inline point V(point s,point e){return point(e.x-s.x,e.y-s.y);} 29 inline double crossP(point a,point b){return a.x*b.y-b.x*a.y;} 30 inline double dotP(point a,point b){return a.x*b.x+a.y*b.y;} 31 struct T{int ispo;point o;}q[600000]; 32 point t[600000];int tnum; 33 point up[600000];int unum; 34 point dw[600000];int dnum; 35 bool ans[600000]; 36 void imerge(int l,int r) 37 { 38 if(l==r)return ; 39 int mid=(l+r)/2; 40 imerge(l,mid);imerge(mid+1,r); 41 tnum=0; 42 for(int i=l;i<=mid;i++) 43 if(!q[i].ispo)t[++tnum]=q[i].o; 44 sort(t+1,t+tnum+1); 45 unum=0; 46 for(int i=1;i<=tnum;i++) 47 { 48 while(unum>1&&crossP(V(up[unum-1],up[unum]),V(up[unum],t[i]))>-eps)unum--; 49 up[++unum]=t[i]; 50 } 51 up[unum+1].x=up[unum].x+eps;up[unum+1].y=-inf; 52 dnum=0; 53 for(int i=tnum;i;i--) 54 { 55 while(dnum>1&&crossP(V(dw[dnum-1],dw[dnum]),V(dw[dnum],t[i]))>-eps)dnum--; 56 dw[++dnum]=t[i]; 57 } 58 dw[dnum+1].x=dw[dnum].x-eps;dw[dnum+1].y=inf; 59 if(tnum!=0) 60 for(int i=mid+1;i<=r;i++) 61 if(q[i].ispo&&ans[i]) 62 { 63 point near; 64 if(q[i].o.y<0) 65 { 66 int L=1,R=unum; 67 while(L<=R) 68 { 69 int Mid=(L+R)/2; 70 if(dotP(q[i].o,V(up[Mid],up[Mid+1]))>-eps)near=up[Mid],R=Mid-1; 71 else L=Mid+1; 72 } 73 } 74 else 75 { 76 int L=1,R=dnum; 77 while(L<=R) 78 { 79 int Mid=(L+R)/2; 80 if(dotP(q[i].o,V(dw[Mid+1],dw[Mid]))<eps)near=dw[Mid],R=Mid-1; 81 else L=Mid+1; 82 } 83 } 84 if(2*near.x*q[i].o.x+2*near.y*q[i].o.y-q[i].o.x*q[i].o.x-q[i].o.y*q[i].o.y<eps)ans[i]=false; 85 } 86 } 87 int main(int argc, char *argv[]) 88 { 89 //freopen("1.in","r",stdin); 90 //freopen("1.out","w",stdout); 91 int n;scanf("%d",&n); 92 for(int i=1;i<=n;i++) 93 { 94 scanf("%d%lf%lf",&q[i].ispo,&q[i].o.x,&q[i].o.y); 95 if(q[i].ispo)ans[i]=true; 96 } 97 for(int i=1;i<=n&&q[i].ispo;i++)ans[i]=false; 98 imerge(1,n); 99 for(int i=1;i<=n;i++) 100 if(q[i].ispo)puts(ans[i]?"Yes":"No"); 101 return 0; 102 }