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 }

 

你可能感兴趣的:(ZOJ)