bzoj2961 共点圆——陈丹琪分治
最近惊讶地发现陈丹琪分治又名时间分治......
写完cash以后,突然就觉得分治法解决一些需要高级数据结构维护的题目非常地爽,于是我就很2b地去做共点圆了。对于一个几乎没有做过计算几何的我,居然还傻傻地以为直接用斜率就可以搞了......并且一开始解不等式居然忘变号了,以为只用维护一个下半凸壳就行了......
以上都是废话。
这个题给过圆心的点,询问点是不是在所有圆内,运用时间分治,我们变成了用[l,mid]段的圆去计算[mid+1,r]段的点,以更新答案。因为这个题中添加操作之间对答案的贡献是互不影响的,这样我们通过分治创造了一种序,就是先给出圆,后计算点。于是这个问题就比价容易了,符合条件的圆心(x,y),一定在2*xo*x+2*yo*y>=xo2+yo2这个半平面内,于是我们对[l,mid]的圆心做一个全凸包,然后二分查找斜率-xo/yo卡到的点,然后判断这个点是不是符合条件就行了。
详细请见2013xhr论文
circle
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #define maxn 600000 7 #define inf 1e12 8 #define eps 1e-9 9 using namespace std; 10 struct query 11 { 12 int tp; 13 double x,y; 14 }q[maxn],p[maxn],up[maxn],dw[maxn]; 15 int ans[maxn]; 16 int n,tot,t1,t2; 17 double fabs(double x) 18 { 19 return (x>0)?x:-x; 20 } 21 query operator -(const query &a,const query &b) 22 { 23 query tmp; 24 tmp.x=a.x-b.x; tmp.y=a.y-b.y; 25 return tmp; 26 } 27 double operator *(const query &a,const query &b) 28 { 29 return a.x*b.y-a.y*b.x; 30 } 31 double operator ^(const query &a,const query&b) 32 { 33 return a.x*b.x+a.y*b.y; 34 } 35 bool operator <(const query &a,const query &b) 36 { 37 return (fabs(a.x-b.x)<eps)?a.y<b.y:a.x<b.x; 38 } 39 40 void ask(int i) 41 { 42 query tmp; 43 if (q[i].y<0) 44 { 45 int l=1,r=t1; 46 while (l<=r) 47 { 48 int mid=(l+r)>>1; 49 if ((q[i]^(up[mid+1]-up[mid]))>-eps) r=mid-1,tmp=up[mid]; 50 else l=mid+1; 51 } 52 } 53 else 54 { 55 int l=1,r=t2; 56 while (l<=r) 57 { 58 int mid=(l+r)>>1; 59 if ((q[i]^(dw[mid]-dw[mid+1]))<eps) r=mid-1,tmp=dw[mid]; 60 else l=mid+1; 61 } 62 } 63 if (2*q[i].x*tmp.x+2*q[i].y*tmp.y-(q[i].x*q[i].x+q[i].y*q[i].y)<eps) ans[i]=0; 64 } 65 66 void solve(int l,int r) 67 { 68 if (l==r) return ; 69 int mid=(l+r)>>1; 70 solve(l,mid); 71 solve(mid+1,r); 72 tot=0; 73 for (int i=l;i<=mid;i++) 74 if (q[i].tp==0) p[++tot]=q[i]; 75 sort(p+1,p+tot+1); 76 t1=t2=0; 77 for (int i=1;i<=tot;i++) 78 { 79 while (t1>=2&&(up[t1]-up[t1-1])*(p[i]-up[t1])>-eps) t1--; 80 up[++t1]=p[i]; 81 } 82 for (int i=tot;i>=1;i--) 83 { 84 while (t2>=2&&(dw[t2]-dw[t2-1])*(p[i]-dw[t2])>-eps) t2--; 85 dw[++t2]=p[i]; 86 } 87 up[t1+1].x=up[t1].x+eps; up[t1+1].y=-inf; 88 dw[t2+1].x=dw[t2].x-eps; dw[t2+1].y=inf; 89 for (int i=mid+1;i<=r;i++) 90 if (q[i].tp==1) if (ans[i]) ask(i); 91 } 92 93 int main() 94 { 95 //freopen("circle.in","r",stdin); 96 //freopen("circle.out","w",stdout); 97 scanf("%d",&n); 98 int now=0; 99 for (int i=1;i<=n;i++) 100 { 101 scanf("%d%lf%lf",&q[i].tp,&q[i].x,&q[i].y); 102 if (q[i].tp==0) now=1; 103 else ans[i]=now; 104 } 105 solve(1,n); 106 for (int i=1;i<=n;i++) 107 if (q[i].tp==1) 108 if (ans[i]==1) 109 printf("Yes\n"); 110 else 111 printf("No\n"); 112 return 0; 113 }
AC without art, no better than WA !