【BZOJ4140】 共点圆加强版
2015-12-01 19:48
357 查看
Description
在平面直角坐标系中,Wayne需要你完成n次操作,操作只有两种:
1.0 x y。表示在坐标系中加入一个以(x, y)为圆心且过原点的圆。
2.1 x y。表示询问点(x, y)是否在所有已加入的圆的内部(含圆周),且至少在一个圆内部(含圆周)。
为了减少你的工作量,题目保证圆心严格在x轴上方(纵坐标为正),且横坐标非零。
Input
第1行一个整数n。
接下来n行,每行第一个数是0或1,分别表示两种操作。
接着有两个实数x和y,具体意义见题面。注意询问进行了加密,x和y需要加上之前回答Yes的数量得到真正的询问。
Output
对于每个询问操作,如果点在所有已加入的圆内(或圆周上),则输出“Yes”(不含引号);否则输出“No”(不含引号)。
Sample Input
5
0 2.000000 3.000000
0 4.000000 1.000000
1 1.000000 1.000000
0 -4.000000 1.000000
1 0.000000 0.000000
Sample Output
Yes
No
HINT
Source
鸣谢talw001上传
改题的人绝对是个大毒瘤!好好地cdq加什么强制在线!
只好上二进制分组了
结果发现自己之前没写过二进制分组并不怎么会写…只好看了一发Claris模板然后幡然醒悟
为什么学的Claris模板然而时间就是比人家多2s
在平面直角坐标系中,Wayne需要你完成n次操作,操作只有两种:
1.0 x y。表示在坐标系中加入一个以(x, y)为圆心且过原点的圆。
2.1 x y。表示询问点(x, y)是否在所有已加入的圆的内部(含圆周),且至少在一个圆内部(含圆周)。
为了减少你的工作量,题目保证圆心严格在x轴上方(纵坐标为正),且横坐标非零。
Input
第1行一个整数n。
接下来n行,每行第一个数是0或1,分别表示两种操作。
接着有两个实数x和y,具体意义见题面。注意询问进行了加密,x和y需要加上之前回答Yes的数量得到真正的询问。
Output
对于每个询问操作,如果点在所有已加入的圆内(或圆周上),则输出“Yes”(不含引号);否则输出“No”(不含引号)。
Sample Input
5
0 2.000000 3.000000
0 4.000000 1.000000
1 1.000000 1.000000
0 -4.000000 1.000000
1 0.000000 0.000000
Sample Output
Yes
No
HINT
Source
鸣谢talw001上传
改题的人绝对是个大毒瘤!好好地cdq加什么强制在线!
只好上二进制分组了
结果发现自己之前没写过二进制分组并不怎么会写…只好看了一发Claris模板然后幡然醒悟
为什么学的Claris模板然而时间就是比人家多2s
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 500010 using namespace std; int n,opt,top,num; int l[32],r1[32],r2[32]; bool t; double A,B,C,sum; double sqr(double x) {return x*x;} struct Point { double x,y; }ins[MAXN],newq[MAXN],q1[MAXN],q2[MAXN]; inline bool cmp1(Point a,Point b) {return a.x==b.x?a.y>b.y:a.x<b.x;} inline bool cmp2(Point a,Point b) {return a.x==b.x?a.y<b.y:a.x<b.x;} inline void rebuild()//重建分组 { while (num&&top-l[num]==l[num]-l[num-1]) num--;l[++num]=top; int L=l[num-1]+1,R=L-1,cnt=0; for (int i=L;i<=top;i++) newq[++cnt]=ins[i];sort(newq+1,newq+cnt+1,cmp1); for (int i=1;i<=cnt;i++) { while (R>L&&(q1[R].y-q1[R-1].y)*(newq[i].x-q1[R].x)<=(newq[i].y-q1[R].y)*(q1[R].x-q1[R-1].x)) R--; q1[++R]=newq[i]; } r1[num]=R;R=L-1;sort(newq+1,newq+cnt+1,cmp2); for (int i=1;i<=cnt;i++) { while (R>L&&(q2[R].y-q2[R-1].y)*(newq[i].x-q2[R].x)>=(newq[i].y-q2[R].y)*(q2[R].x-q2[R-1].x)) R--; q2[++R]=newq[i]; } r2[num]=R; } inline double calc(Point x) {return A*x.x+B*x.y;} inline bool query1(int l,int r) { int mid1,mid2,len;double s1,s2; while (l<=r) { len=(r-l)/3;mid1=l+len;mid2=r-len;s1=calc(q1[mid1]);s2=calc(q1[mid2]); if (s1<s2) {if (s1<C) return t=1;r=mid2-1;} else {if (s2<C) return t=1;l=mid1+1;} } return 0; } inline bool query2(int l,int r) { int mid1,mid2,len;double s1,s2; while (l<=r) { len=(r-l)/3;mid1=l+len;mid2=r-len;s1=calc(q2[mid1]);s2=calc(q2[mid2]); if (s1<s2) {if (s1<C) return t=1;r=mid2-1;} else {if (s2<C) return t=1;l=mid1+1;} } return 0; } inline void Query() { t=0; for (int i=1;i<=num;i++) { if (B<0) query1(l[i-1]+1,r1[i]); else query2(l[i-1]+1,r2[i]); if (t) return; } } int main() { scanf("%d",&n); while (n--) { scanf("%d%lf%lf",&opt,&A,&B);A+=sum,B+=sum; if (opt==0) ins[++top].x=A,ins[top].y=B,rebuild(); else { if (!top) {puts("No");continue;} C=sqr(A)+sqr(B);A*=2;B*=2;Query();puts(t?"No":"Yes"); if (!t) sum++; } } }
相关文章推荐
- [Poj 1276] Cash Machine
- 2015河南科技学院高校CSDN俱乐部--PPT操作讲解
- 修改某个表给某个用户更新权限
- jsp servlet通信
- 浅谈Spring事务隔离级别
- [leetcode] 203. Remove Linked List Elements
- Java简单爬虫示例
- jsp调用javabean
- 关于数据预处理的相关技巧
- 面向企业应用的Android开发从入门到精通
- 11月30号 MacOSX安装
- PAT Basic 1007
- leetcode Minimum Height Trees
- HTML标签以及各个标签属性大全(网页制作必备)
- 修改数据库密码
- Light OJ 1008 Fibsieve`s Fantabulous Birthday【规律】
- 企业应用打包的时候 修改ipa包的bundle identifier
- 禁用驱动签名强制
- 129、Sum Root to Leaf Numbers
- 【Codeforces 343D】Water Tree dfs序建树+线段树