【BZOJ2961】共点圆(CDQ分治)

题面

BZOJ

题解

设询问点\((x,y)\),圆心是\((X,Y)\)

那么如果点在园内的话就需要满足

\((X-x)^2+(Y-y)^2\le X^2+Y^2\)

拆开之后就变成了

\(x^2+y^2-2xX\le 2yY\)

除过去就是\(-\frac{x}{y}X+\frac{x^2+y^2}{2y}\le Y\)

显然左边是一个直线,那么,这个式子的含义就是,

对于任意\((X,Y)\),在\(X\)处的函数值都要小于\(Y\),

即这个直线在所有的圆心下方。

那么维护一下下凸壳,每次拿斜率去切凸壳,检查一下截距就好了。

当然,上面是假装\(y>0\),如果\(y<0\)的话需要变号,变成了所有圆心都在直线的下方了

这里需要维护一个上凸壳。

用\(CDQ\)分治就可以很好的维护这些东西了。

然而我这个傻逼这都不会写

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MAX 500500
#define Sqr(x) ((x)*(x))
const double eps=1e-8;
struct Opt{int op,id;double x,y,k;}p[MAX],tmp[MAX],S1[MAX],S2[MAX];
bool operator<(Opt a,Opt b){return a.k<b.k;}
bool cmp(Opt a,Opt b){return a.id<b.id;}
double Slope(Opt a,Opt b)
{
if(fabs(a.x-b.x)<eps)return a.y<b.y?1e18:-1e18;
return (a.y-b.y)/(a.x-b.x);
}
double Dis(Opt a,Opt b){return sqrt(Sqr(a.x-b.x)+Sqr(a.y-b.y));}
bool ans[MAX];
int n;
void CDQ(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1,t1=l,t2=mid+1,tp1=0,tp2=0;
for(int i=l;i<=r;++i)
if(p[i].id<=mid)tmp[t1++]=p[i];
else tmp[t2++]=p[i];
for(int i=l;i<=r;++i)p[i]=tmp[i];
CDQ(l,mid);
for(int i=l;i<=mid;++i)
{
if(p[i].op)continue;
while(tp1>1&&Slope(S1[tp1-1],p[i])+eps>Slope(S1[tp1-1],S1[tp1]))--tp1;S1[++tp1]=p[i];
while(tp2>1&&Slope(S2[tp2-1],p[i])-eps<Slope(S2[tp2-1],S2[tp2]))--tp2;S2[++tp2]=p[i];
}
t1=tp1,t2=1;
for(int i=mid+1;i<=r;++i)
{
if(!p[i].op)continue;
if(p[i].y<0)
{
while(t1>1&&Slope(S1[t1-1],S1[t1])<p[i].k)--t1;
if(t1>0&&Dis(S1[t1],S1[0])<Dis(S1[t1],p[i]))ans[p[i].id]=false;
}
else
{
while(t2<tp2&&Slope(S2[t2],S2[t2+1])<p[i].k)++t2;
if(t2<=tp2&&Dis(S2[t2],S2[0])<Dis(S2[t2],p[i]))ans[p[i].id]=false;
}
}
CDQ(mid+1,r);
t1=l;t2=mid+1;
for(int i=l;i<=r;++i)
if(t2>r||(t1<=mid&&p[t1].x<p[t2].x))tmp[i]=p[t1++];
else tmp[i]=p[t2++];
for(int i=l;i<=r;++i)p[i]=tmp[i];
}
int main()
{
freopen("2961.in","r",stdin);
freopen("2961.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(int i=1,opt,sum=0;i<=n;++i)
{
double x,y;
cin>>opt>>x>>y;
if(opt==0)p[i]=(Opt){0,i,x,y,0},++sum;
else p[i]=(Opt){1,i,x,y,0};
if(fabs(y)>eps)p[i].k=-x/y;else p[i].k=1e18;
if(opt==1)ans[i]=(bool)sum;
}
sort(&p[1],&p[n+1]);CDQ(1,n);
sort(&p[1],&p[n+1],cmp);
for(int i=1;i<=n;++i)if(p[i].op)puts(ans[i]?"Yes":"No");
return 0;
}

【BZOJ2961】共点圆(CDQ分治)的更多相关文章

  1. [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_ ...

  2. BZOJ2961 共点圆[CDQ分治]

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

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

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

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

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

  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. bzoj 2961 共点圆 cdq+凸包+三分

    题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...

  9. 【bzoj2961】 共点圆

    http://www.lydsy.com/JudgeOnline/problem.php?id=2961 (题目链接) 题意 按照一定的顺序给出一些圆和一些点,对于每一个点问是否在所有圆内. Solu ...

随机推荐

  1. birt 访问频繁报错Cannot create JDBC driver of class '' for connect URL 'null' java.sql.SQLException: No suitable driver

    一般birt项目都是部署tomcat启动.这个问题大概率是因为没有配置JNDI数据源的原因. 参考链接: https://www.cnblogs.com/xdp-gacl/p/3951952.html

  2. 前端开发利器 livereload -- 从此告别浏览器F5键

    各位从事前端开发的童鞋们,大家每天coding && coding,然后F5 && F5,今天推荐一个静态文件在浏览器中自动更新的扩展 livereload,不同手动刷 ...

  3. OpenFastPath(1):快平面接口是否支持多ip

    1.配置环境 fp0接口上配置两个IP地址: fp0       Link encap:Ethernet  HWaddr 00:0c:29:30:38:db inet addr:192.168.56. ...

  4. linq与lambda 常用查询语句写法对比

    LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量中被查询的值 [group by 条件] Lambda ...

  5. 阿里云ubuntu16.04安装beef

    0x0 前言 环境:阿里云轻量服务器ubuntu16.04 需要安装2.4以上版本的ruby:https://www.cnblogs.com/Rain99-/p/10666247.html 参考资料 ...

  6. e2fsck命令详解

    原文链接:https://ipcmen.com/e2fsck Linux e2fsck命令用于检查使用 Linux ext2 档案系统的 partition 是否正常工作. 语法 e2fsck [-p ...

  7. 7行Python代码的人脸识别

    随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域众多,图像识别中的人脸识别是其中一个有趣的分支.百度的BFR,Face++的开放平台,汉王,讯飞等等都提供了人脸识别的A ...

  8. 《Spring2之站立会议1》

    <Spring2之站立会议1> 昨天,查找了关于建立起服务器和客户端两端的连接的资料,并学习了如何写把两者建立起来的代码: 今天,模仿着相关资料,分别写了客户端和服务器两端的代码: 遇到的 ...

  9. git 的认识

    简单说,三个概念:远程仓库.本地仓库.本地工作目录.clone是从远程仓库上down下本地仓库+工作目录:本地仓库就是工作目录里.git这个目录commit是把工作目录的修改提交给本地仓库pull把远 ...

  10. synchronized、锁、多线程同步的原理是咋样

    先综述个结论: 一般说的synchronized用来做多线程同步功能,其实synchronized只是提供多线程互斥,而对象的wait()和notify()方法才提供线程的同步功能. 一般说synch ...