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 }

 

posted @ 2013-09-10 13:00  zhuohan123  阅读(543)  评论(0编辑  收藏  举报