【BZOJ2961】【Codevs2003】共点圆
来源:互联网 发布:反网络尖兵 编辑:程序博客网 时间:2024/05/24 15:37
2961: 共点圆
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 333 Solved: 141
[Submit][Status][Discuss]
Description
在平面直角坐标系中,Wayne需要你完成n次操作,操作只有两种:
1.0 x y。表示在坐标系中加入一个以(x, y)为圆心且过原点的圆。
2.1 x y。表示询问点(x, y)是否在所有已加入的圆的内部(含圆周),且至少在一个圆内部(含圆周)。
为了减少你的工作量,题目保证圆心严格在x轴上方(纵坐标为正),且横坐标非零。
Input
第1行一个整数n。
接下来n行,每行第一个数是0或1,分别表示两种操作。
接着有两个实数x和y,具体意义见题面。
Output
对于每个询问操作,如果点在所有已加入的圆内(或圆周上),则输出“Yes”(不含引号);否则输出“No”(不含引号)。
Sample Input
5
0 2.0000 3.0000
0 4.0000 1.0000
1 1.000000 1.000000
0 -3.0000 2.0000
1 1.000000 1.000000
Sample Output
Yes
No
HINT
对于100%的数据,n≤500000,所有坐标绝对值不超过10000。
输入数据保证圆心纵坐标为正,横坐标非零。
圆心坐标保留4位小数,询问点坐标保留6位小数,请选手注意控制精度。
Source
中国国家队清华集训 2012-2013 第二天
麻麻我终于会写半平面交了QUQ本来想练cdq玩的顺便学会了半平面交
虽然我的代码跑的奇慢荣登BZOJ倒数rank5但是毕竟A了不是吗233
这么简单的东西也不打太多注释了会被鄙视的(/ω\)
就是普通的凸包啊。。。
把插入的圆变成凸包点当半平面看凸包是否全部点在半平面内
具体做法2013集训队论文XHR神犇讲的很清楚了0-0我也不多说什么了(/ω\)
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 500100#define MAXDBL 1e20#define eps 1e-9using namespace std;int n;bool ans[MAXN];int flag;struct Query{ int t; int op; double x,y; double k; bool operator <(const Query& a)const{ return x<a.x; }}q[MAXN],newq[MAXN];int num;bool com(Query a,Query b){ return a.t<b.t;}double slope(int a,int b){ if (!b) return -MAXDBL; if (fabs(q[a].x-q[b].x)<eps) return MAXDBL; return (q[b].y-q[a].y)/(q[b].x-q[a].x);}double dis(int a,int b){ return sqrt((q[a].x-q[b].x)*(q[a].x-q[b].x)+(q[a].y-q[b].y)*(q[a].y-q[b].y));}int stack1[MAXN],stack2[MAXN];//分别维护上凸线(stack1)和下凸线(stack2)bool comp(Query a,Query b){ return a.k<b.k;}void solve(int l,int r){ int mid=(l+r)>>1,tp1=l,tp2=mid+1; if (l==r) return; for (int i=l;i<=r;i++) if (q[i].t<=mid) newq[tp1++]=q[i]; else newq[tp2++]=q[i]; memcpy(q+l,newq+l,sizeof(Query)*(r-l+1)); solve(l,mid); int top1=0,top2=0,j=1; for (int i=l;i<=mid;i++) { if (q[i].op==1) continue; while (top1>1&&(slope(stack1[top1-1],stack1[top1])-slope(stack1[top1-1],i))<eps) stack1[top1--]=0; stack1[++top1]=i; while (top2>1&&(slope(stack2[top2-1],stack2[top2])-slope(stack2[top2-1],i))>eps) stack2[top2--]=0; stack2[++top2]=i; } for (int i=mid+1;i<=r;i++) { if (q[i].op==0) continue; if (q[i].y>eps) { while (j<top2&&slope(stack2[j],stack2[j+1])<q[i].k) stack2[j++]=0; if (j<=top2&&dis(stack2[j],0)<dis(stack2[j],i)) ans[q[i].t]=1; } else { while (top1>1&&slope(stack1[top1-1],stack1[top1])<q[i].k) stack1[top1--]=0; if(stack2[j]) printf("%lf %lf\n",q[stack2[j]].x,q[stack2[j]].y); if (top1>=1&&dis(stack2[j],0)<dis(stack2[j],i)) ans[q[i].t]=1; } } solve(mid+1,r); tp1=l;tp2=mid+1; for (int i=l;i<=r;i++) if (tp1<=mid&&q[tp1]<q[tp2]||tp2>r) newq[i]=q[tp1++]; else newq[i]=q[tp2++]; memcpy(q+l,newq+l,sizeof(Query)*(r-l+1));}int main(){ scanf("%d",&n); q[0].x=0;q[0].y=0; for (int i=1;i<=n;i++) ans[i]=0; for (int i=1;i<=n;i++) { scanf("%d%lf%lf",&q[i].op,&q[i].x,&q[i].y); if (fabs(q[i].y)<=eps) q[i].k=MAXDBL; else q[i].k=-q[i].x/q[i].y; q[i].t=i; } sort(q+1,q+n+1,comp); solve(1,n); sort(q+1,q+n+1,com); for (int i=1;i<=n;i++) if (q[i].op==1) { if (!ans[q[i].t]&&flag) puts("Yes"); else puts("No"); } else if (!flag) flag=1;}
- 【BZOJ2961】【Codevs2003】共点圆
- bzoj2961【cdq分治】
- 【BZOJ4140】 共点圆加强版
- BZOJ 2961: 共点圆
- bzoj4140共点圆加强版
- bzoj 2961: 共点圆 cdq分治
- 【圆的反演变换+cdq分治】共点圆
- BZOJ 2961 共点圆 CDQ分治+凸包
- [CDQ分治 凸包] BZOJ 2961 共点圆
- bzoj 2961 共点圆 CDQ分治 凸包
- [二进制分组] BZOJ 4140 共点圆加强版
- [二进制分组] BZOJ4140. 共点圆加强版
- BZOJ 4140: 共点圆加强版 [二进制分组]
- 台湾--电话正则表达式
- IE7以下不兼容JS的onsubmit方法
- 1.函数返回值的应用
- 使用 typedef 简化函数指针
- 解决存到数据库里中文乱码问题
- 【BZOJ2961】【Codevs2003】共点圆
- 澳门--电话正则表达式
- VS2013不能新建C和C++项目的解决办法
- Unity for Absolute Beginners(一)
- 225 - Golygons Golygons 暴力
- 自动化测试的五大原则
- java实现mongodb的dbutils
- 香港--电话正则表达式
- hive的使用和优化笔记