更新:此题我的代码设置eps=1e-8会WA,现在改为1e-9貌似T了

此题网上的大部分做法是cdq分治+凸包,然而我觉得太烦了,于是自己口胡了一个k-d树做法:

加入一个圆$(x,y)$,直接在k-d树上加入这个点即可,注意要打rebuild否则会T。

查询一个点$(x_0,y_0)$是否在所有的圆上时:

我们设当前需要判断一个圆$(x,y)$是否覆盖该点,通过简单的分析,可以列出以下式子:

$(x-x_0)^2+(y-y_0)^2≤x_0^2+y_0^2$

我们不妨设$y_0>0$通过简单变式和移项,我们可以得到:

$y \geq -\frac{x_0}{y_0}x+\frac{x_0^2+y_0^2}{2y}$

我们将$ -\frac{x_0}{y_0} $和$ \frac{x_0^2+y_0^2}{2y} $视作常数,得到$y≤kx+b$,这是啥?一个半平面啊!!

问题即转化为了当前k-d树中是否所有点均在该半平面内,直接在k-d树中查询即可(实际上还需要有点思考量的分类讨论)

对于$y_0<0$的情况,部分符号需做些许更改。对于$y_0=0$的情况,需要特殊讨论!!(大概是$x<\frac{x_0}{2}$)

然后就没啦,时间复杂度$O(n log n+n^{1.5})$

PS:千万要记得打y=0的情况(我就被这个卡了很久)

 #include<bits/stdc++.h>
#define M 500000
#define eps 1e-9
#define INF 1e20
using namespace std; #define MFLONG 13000000
#define NUM(x) ((48<=x&&x<=57)||x=='-')
char _c[MFLONG],_w[MFLONG]={};int _ns=,_nw=;int _x[],_ld;
inline void rd(int &_q){int _fu;if(_c[_ns]==) return;while(!NUM(_c[_ns])) _ns++;if(_c[_ns]=='-') _fu=-,_ns++;else _fu=;_q=;while(NUM(_c[_ns])) _q=_q*+_c[_ns++]-;_q=_fu*_q;}
inline void rd(double &X)
{
double x=,f=;
for (;_c[_ns]<''||_c[_ns]>'';_ns++) if (_c[_ns]=='-') f=-;
for (;_c[_ns]>=''&&_c[_ns]<='';_ns++) x=x*+_c[_ns]-'';
if (_c[_ns]!='.') {X=x*f;return;} _ns++;
for (double hh=0.1;_c[_ns]>=''&&_c[_ns]<='';_ns++,hh=hh/) x+=(_c[_ns]-'')*hh;
X=x*f;
} int D;
struct node{
double max[],min[],a[];
int l,r,siz;
node(){
max[]=max[]=a[]=a[]=l=r=siz=;
min[]=min[]=INF;
}
void clear(){
max[]=max[]=a[]=a[]=l=r=siz=;
min[]=min[]=INF;
}
node(double x,double y){
max[]=max[]=l=r=siz=;
min[]=min[]=INF;
a[]=x; a[]=y;
}
friend bool operator <(node a,node b){return a.a[D]<b.a[D];}
}a[M]; int root=,use=,reb=,rebfa=,rebd=; void insert(int &x,int fa,int d,node k){
if(!x){x=++use; a[x]=k;}
else{
if(k.a[d]<a[x].a[d]) insert(a[x].l,x,d^,k);
else insert(a[x].r,x,d^,k);
}
a[x].siz++;
a[x].max[]=max(a[x].max[],k.a[]); a[x].min[]=min(a[x].min[],k.a[]);
a[x].max[]=max(a[x].max[],k.a[]); a[x].min[]=min(a[x].min[],k.a[]);
if(max(a[a[x].l].siz,a[a[x].r].siz)>a[x].siz*0.77) reb=x,rebfa=fa,rebd=d;
} int id[M]={},cnt=;
bool cmp(int x,int y){return a[x]<a[y];}
void bl(int x){if(!x) return;id[++cnt]=x;bl(a[x].l); bl(a[x].r);}
void rebuild(int &x,int l,int r,int d){
if(l>r) {x=; return;}
int mid=(l+r)>>; D=d;
nth_element(id+l,id+mid,id+r+,cmp); x=id[mid];
a[x].max[]=a[x].min[]=a[x].a[];
a[x].max[]=a[x].min[]=a[x].a[];
rebuild(a[x].l,l,mid-,d^); rebuild(a[x].r,mid+,r,d^);
a[x].siz=a[a[x].l].siz+a[a[x].r].siz+;
for(int i=;i<;i++)
a[x].max[i]=max(a[x].max[i],max(a[a[x].l].max[i],a[a[x].r].max[i])),
a[x].min[i]=min(a[x].min[i],min(a[a[x].l].min[i],a[a[x].r].min[i]));
}
void rebuild(){
if(!reb) return;
bl(reb);
if(!rebfa) rebuild(root,,cnt,rebd);
else{
if(a[rebfa].l==reb) rebuild(a[rebfa].l,,cnt,rebd);
else rebuild(a[rebfa].r,,cnt,rebd);
}
cnt=reb=rebfa=;
} bool queryl(int x,double k,double b){
if(!x) return ;
if(k>&&a[x].max[]*k+b<a[x].min[]-eps) return ;
if(k>&&a[x].min[]*k+b>=a[x].max[]) return ;
if(k>&&a[x].a[]*k+b<a[x].a[]+eps) return ; if(k<=&&a[x].max[]*k+b>=a[x].max[]-eps) return ;
if(k<=&&a[x].min[]*k+b<a[x].min[]) return ;
if(k<=&&!(a[x].a[]*k+b>a[x].a[]-eps)) return ; return queryl(a[x].l,k,b)&queryl(a[x].r,k,b);
} bool queryr(int x,double k,double b){
if(!x) return ;
if(k>&&a[x].max[]*k+b<a[x].min[]) return ;
if(k>&&a[x].min[]*k+b>a[x].max[]-eps) return ;
if(k>&&a[x].a[]*k+b>a[x].a[]-eps) return ; if(k<=&&a[x].max[]*k+b>a[x].max[]) return ;
if(k<=&&a[x].min[]*k+b<a[x].min[]+eps) return ;
if(k<=&&!(a[x].a[]*k+b<a[x].a[]+eps)) return ; return queryr(a[x].l,k,b)&queryr(a[x].r,k,b);
} bool queryx(int x,int k,double l){
if(!x) return ;
if(k>&&l<=a[x].min[]+eps) return ;
if(k>&&l>a[x].max[]-eps) return ;
if(k>&&l>a[x].a[]-eps) return ; if(k<&&a[x].max[]-eps<=l) return ;
if(k<&&l<a[x].min[]+eps) return ;
if(k<&&l>a[x].a[]) return ; return queryx(a[x].l,k,l)&queryx(a[x].r,k,l);
} int main(){
//fread(_c,1,MFLONG,stdin);
int n; //rd(n);
scanf("%d",&n);
while(n--){
int op; double x,y;
//rd(op);rd(x);rd(y);
scanf("%d%lf%lf",&op,&x,&y);
if(op==){
insert(root,,,node(x,y));
rebuild();
}else{
if(fabs(y)<=eps&&fabs(x)<=eps){
printf("Yes\n");
continue;
}
if(fabs(y)<eps){
bool ck=queryx(root,(x>?:-),(x*x)/x/.);
if(ck&&use) puts("Yes"); else puts("No");
continue;
}
bool ck; double k,b;
b=(x*x+y*y)/(*y); k=-x/y;
if(y<) ck=queryl(root,k,b);
else ck=queryr(root,k,b);
if(ck&&use) puts("Yes"); else puts("No");
}
}
}

【bzoj2961】共点圆 k-d树的更多相关文章

  1. BZOJ2961 共点圆[CDQ分治]

    题面 bzoj 其实就是推一下圆的式子 长成这个样子 假设要查询的点是(x, y) 某个圆心是(p, q) \((x - p)^2 + (y - q)^2 \leq p^2 + q^2\) 变成 \( ...

  2. bzoj2961 共点圆 (CDQ分治, 凸包)

    /* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面 然后cdq分治就可以了 代码基本是抄的, */ #inc ...

  3. BZOJ2961: 共点圆(CDQ分治+凸包)

    题面 传送门 题解 这题解法真是多啊--据说可以圆反演转化为动态插入半平面并判断给定点是否在半平面交中,或者化一下改成给定点判断是否所有点都在某一个半平面内-- 鉴于圆反演我也不会,这里讲一下直接推的 ...

  4. [BZOJ2961] 共点圆 [cdq分治+凸包]

    题面 BZOJ传送门 思路 首先考虑一个点$(x_0,y_0)$什么时候在一个圆$(x_1,y_1,\sqrt{x_1^2+y_1^2})$内 显然有:$x_1^2+y_1^2\geq (x_0-x_ ...

  5. BZOJ2961: 共点圆

    好久没发了 CDQ分治,具体做法见XHR的论文… /************************************************************** Problem: 29 ...

  6. bzoj2961 共点圆 bzoj 4140

    题解: 比较水的一道题 首先我们化简一下式子发现是维护xxo+yyo的最值 显然是用凸包来做 我们可以直接用支持插入删除的凸包 也是nlogn的 因为没有强制在线,我们也可以cdq,考虑前面一半对答案 ...

  7. [BZOJ2961]共点圆-[凸包+cdq分治]

    Description 传送门 Solution 考虑对于每一个点: 设圆的坐标为(x,y),点的坐标为(x0,y0).依题意得,当一个点在圆里,需要满足(x-x0)2+(y-y0)2<=x2+ ...

  8. 【BZOJ2961】共点圆(CDQ分治)

    [BZOJ2961]共点圆(CDQ分治) 题面 BZOJ 题解 设询问点\((x,y)\),圆心是\((X,Y)\) 那么如果点在园内的话就需要满足 \((X-x)^2+(Y-y)^2\le X^2+ ...

  9. 【BZOJ4140】共点圆加强版(二进制分组)

    [BZOJ4140]共点圆加强版(二进制分组) 题面 BZOJ 题解 我卡精度卡了一天.... 之前不强制在线的做法是\(CDQ\)分治,维护一个凸壳就好了. 现在改成二进制分组,每次重建凸壳就好了. ...

  10. HDU 2157 How many ways??:矩阵快速幂【i到j共经过k个节点的方法数】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2157 题解: 给你一个有向图,n个节点m条边,问你从i到j共经过k个节点的方法数(不算i点). 题解: ...

随机推荐

  1. 多网卡的7种bond模式原理 For Linux

    多网卡的7种bond模式原理 Linux 多网卡绑定 网卡绑定mode共有七种(0~6) bond0.bond1.bond2.bond3.bond4.bond5.bond6 常用的有三种 mode=0 ...

  2. KbmMW 服务器架构简介

    kbmmw 由于文档比较少,很多同学开始用时很难理解.一直准备写一个关于kbmmw 架构的东西. 这几天与红鱼儿(blog)研究服务器线程时,整理了一下,大概画了一下kbmmw (版本4.5)服务器的 ...

  3. 客户被绑,蒙眼,惊问:“想干什么?” 对方不语,鞭笞之,客户求饶:“别打,要钱?” 又一鞭,“十万够不?” 又一鞭,“一百万?” 又一鞭。客户崩溃:“你们TMD到底要啥?” “要什么?...

    1.  客户被绑,蒙眼,惊问:“想干什么?”     对方不语,鞭笞之,客户求饶:“别打,要钱?”     又一鞭,“十万够不?”     又一鞭,“一百万?”     又一鞭.客户崩溃:“你们TMD ...

  4. 着重基础之—MySql 不能遗忘的索引操作

    着重基础之—MySql 不能遗忘的索引操作 关于MySql索引的基础知识我就不在这里写了,我不太想当信息的搬运工. 技巧分享:Workbench 作为一款专为MySQL设计的ER/数据库建模工具.除了 ...

  5. 树莓派安装mono

    http://www.mono-project.com/download/ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --r ...

  6. Windows could not set the offline local information.Error code:0X80000001解决方法

    我的笔记本是联想Y460(白色) 昨天在重装系统的时候遇到如下错误:Windows could not set the offline local information.Error code:0X8 ...

  7. 【翻译】JavaScript框架的最终指南

    翻译原文链接 我的翻译小站 紧跟JavaScript框架的脚步是一个挑战.现在有太多的框架,几乎一个月就会出来一个新的.那么如何知道到底哪一个比较合适你的项目呢?它们分别有什么优点和缺点呢?你要如何开 ...

  8. springmvc 孔浩 hibernate

    以上为项目文件 用到的jar包:http://pan.baidu.com/s/1kT1Rsqj 1. model-User 2. beans.xml-去哪些包中找annotation:查找相应的实体类 ...

  9. Android-Thread线程的状态

    介绍Thread线程的状态之前,必须要讲解CPU执行线程的随机性: 例如:有五个线程,CPU中央处理器,在执行这五个线程的时候,有可能先执行Thread-0,有可能先执行Thread-3,等等,都有可 ...

  10. NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(转载)

    原文地址:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html 阅读目录 1.基本介绍 ...