bzoj 2961 共点圆 CDQ分治 凸包
2017-01-04 21:40
423 查看
凸包一向写得蛋疼,何况这题有两个凸包。。。
条件(x1−x)2+(y1−y)2>x2+y2
化一下可以变成 x12+y12−2xx1−2yy1>0
最大化x12+y12−2xx1−2yy1 就是最小化b=2xx1+2yy1
y=by1+(−x1y1)x
由于不知道y1正负,因此需要维护凹凸两个凸包
CDQ维护一下凸包
条件(x1−x)2+(y1−y)2>x2+y2
化一下可以变成 x12+y12−2xx1−2yy1>0
最大化x12+y12−2xx1−2yy1 就是最小化b=2xx1+2yy1
y=by1+(−x1y1)x
由于不知道y1正负,因此需要维护凹凸两个凸包
CDQ维护一下凸包
#include <bits/stdc++.h> using namespace std; #define N 510000 const double inf=1e18,eps=1e-7; int n,h1,h2,r1,r2; int tp ,q1 ,q2 ,pos ; double X ,Y ,mx,mn,val ; int cmp1(int x,int y) { if(fabs(X[x]-X[y])<eps)return Y[x]<Y[y]; return X[x]<X[y]; } int cmp2(int x,int y) { if(fabs(X[x]-X[y])<eps)return Y[x]>Y[y]; return X[x]<X[y]; } int cmp3(int x,int y){return X[x]/Y[x]<X[y]/Y[y];} void solve(int l,int r) { if(l==r)return; int mid=(l+r)>>1; solve(l,mid); for(int i=l;i<=r;i++)pos[i]=i; h1=h2=1;r1=r2=0; mx=-inf;mn=inf; for(int i=l;i<=r;i++)pos[i]=i; sort(pos+l,pos+mid+1,cmp1); for(int i=l,t1,t2,t3;i<=mid;i++)if(tp[pos[i]]==0) { if(r1>=2)t1=q1[r1-1],t2=q1[r1];t3=pos[i]; while(r1>=2&&(Y[t3]-Y[t2])*(X[t2]-X[t1])+eps>(Y[t2]-Y[t1])*(X[t3]-X[t2])) r1--,t2=t1,t1=q1[r1-1]; q1[++r1]=t3; mx=max(mx,X[t3]);mn=min(mn,X[t3]); } sort(pos+l,pos+mid+1,cmp2); for(int i=l,t1,t2,t3;i<=mid;i++)if(tp[pos[i]]==0) { if(r2>=2)t1=q2[r2-1],t2=q2[r2];t3=pos[i]; while(r2>=2&&(Y[t3]-Y[t2])*(X[t2]-X[t1])<eps+(Y[t2]-Y[t1])*(X[t3]-X[t2])) r2--,t2=t1,t1=q2[r2-1]; q2[++r2]=t3; } sort(pos+mid+1,pos+r+1,cmp3); for(int i=mid+1,t,t1,t2;i<=r;i++)if(tp[pos[i]]==1&&r1>=h1) { t=pos[i]; if(fabs(Y[t])<eps) { val[t]=min(val[t],X[t]*mx); val[t]=min(val[t],X[t]*mn); } else if(Y[t]>0) { t1=q2[r2],t2=q2[r2-1]; while(r2>h2&&X[t]*X[t1]+Y[t]*Y[t1]>X[t]*X[t2]+Y[t]*Y[t2]) r2--,t1=t2,t2=q2[r2-1]; val[t]=min(val[t],X[t]*X[q2[r2]]+Y[t]*Y[q2[r2]]); } else { t1=q1[h1],t2=q1[h1+1]; while(r1>h1&&X[t]*X[t1]+Y[t]*Y[t1]>X[t]*X[t2]+Y[t]*Y[t2]) h1++,t1=t2,t2=q1[h1+1]; val[t]=min(val[t],X[t]*X[q1[h1]]+Y[t]*Y[q1[h1]]); } } solve(mid+1,r); } double dis(int x,int y) { return sqrt((X[x]-X[y])*(X[x]-X[y])+(Y[x]-Y[y])*(Y[x]-Y[y])); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%lf%lf",&tp[i],&X[i],&Y[i]),val[i]=inf; solve(1,n); for(int i=1;i<=n;i++) if(tp[i]==1) puts(X[i]*X[i]+Y[i]*Y[i]-2*val[i]>0||val[i]==inf ? "No":"Yes"); return 0; }
相关文章推荐
- [CDQ分治 凸包] BZOJ 2961 共点圆
- bzoj2961 共点圆(cdq分治维护凸包,计算几何)
- BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包
- bzoj 2961 共点圆 cdq+凸包+三分
- [DP 斜率优化 CDQ分治||动态维护凸包] BZOJ 1492 [NOI2007]货币兑换Cash
- bzoj 2961: 共点圆 cdq分治
- BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包
- [BZOJ1492][NOI2007]货币兑换Cash(斜率优化dp+splay|cdq分治维护凸包)
- bzoj2961【cdq分治】
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
- 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
- 【bzoj4311】向量 线段树对时间分治+STL-vector维护凸包
- 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治
- BZOJ 2225 [Spoj 2371]Another Longest Increasing(CDQ分治)
- BZOJ 1537 cdq分治
- BZOJ 3295 动态逆序对(CDQ分治)
- 【BZOJ3963】【ACM-WF2011】MachineWorks(CDQ分治+斜率优化)
- BZOJ 3262 cdq分治 OR 树套树
- BZOJ - 3262 陌上花开 CDQ分治 三维偏序
- bzoj3672 [ NOI2014 ] -- 树上CDQ分治 + 斜率优化DP