题面

BZOJ传送门

思路

首先考虑一个点$(x_0,y_0)$什么时候在一个圆$(x_1,y_1,\sqrt{x_12+y_12})$内

显然有:$x_12+y_12\geq (x_0-x_1)2+(y_0-y_1)2$

化简:$2x_0x_1+2y_0y_1\geq x_02+y_02$

所有含$x_1,y_1$的项挪到同一边,除掉一个$2y_0$(假设它是正的),得到:

$y_1\geq -\frac{x_0}{y_0}x_1+\frac{x_02+y_02}{2y_0}$

如果是负的:

$y_1\leq -\frac{x_0}{y_0}x_1+\frac{x_02+y_02}{2y_0}$

DUANG!半平面来了

那么现在的询问变成了:给定一个半平面,问是不是所有的点都在这个半平面的上方(或者下方)

显然,我们如果维护了所有输入节点的上下凸包,这个问题就迎刃而解了

众所周知,维护动态上下凸壳可以用$set$或者平衡树做到$O(n\log n)$

然而博主并不想写这种东西

所以他写了非常沙雕的cdq分治23333

分治

分治开始之前先按照所有询问点的斜率排个序(非询问点不管)

我们对时间顺序分治

进入分治后,首先分治左区间,返回按照横坐标排好序的左区间所有点

求出左区间中所有非询问的点的上下凸壳

然后对右边的所有询问,因为一开始排好序了,所以直接在凸壳上顺次双指针过去

注意:$y_0 > 0$的时候所有点在直线上方,用的是下凸包,反之亦然

最后分治右区间,按照x坐标归并排序,合并左右区间

就是个很模板的cdq斜率分治

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define sqr(x) ((x)*(x))
#define eps 1e-10
#define ll long long
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
struct node{
double x,y,k;
int id,qid,op;
inline friend double slope(const node &a,const node &b){return ((fabs(a.x-b.x)<eps)?(1e30):((a.y-b.y)/(a.x-b.x)));}
inline friend double dis(const node &a,const node &b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
inline friend double rad(const node &a){return sqrt(sqr(a.x)+sqr(a.y));}
}a[500010],tmp[500010],q1[500010],q2[500010];//q1 up q2 down
int n,top1,top2;bool ans[500010];
inline bool cmp(const node &a,const node &b){return a.k<b.k;}
void solve(int l,int r){
if(l==r) return;
int i,t1,t2,mid=(l+r)>>1; t1=l;t2=mid+1;
for(i=l;i<=r;i++){
if(a[i].id<=mid) tmp[t1++]=a[i];
else tmp[t2++]=a[i];
}
memcpy(a+l,tmp+l,sizeof(node)*(r-l+1)); solve(l,mid); top1=top2=0;
for(i=l;i<=mid;i++){
if(a[i].op) continue;
while(top1>1&&slope(q1[top1-1],q1[top1])<slope(q1[top1],a[i])+eps) top1--;
q1[++top1]=a[i];
while(top2>1&&slope(q2[top2-1],q2[top2])+eps>slope(q2[top2],a[i])) top2--;
q2[++top2]=a[i];
} t1=t2=1;
for(i=mid+1;i<=r;i++){
if(!a[i].op) continue;
if(a[i].y>0){
while(t2<top2&&slope(q2[t2],q2[t2+1])<a[i].k) t2++;
if(t2<=top2) ans[a[i].qid]&=(dis(a[i],q2[t2])<rad(q2[t2]));
}
else{
while(t1<top1&&slope(q1[top1-1],q1[top1])<a[i].k) top1--;
if(t1<=top1) ans[a[i].qid]&=(dis(a[i],q1[top1])<rad(q1[top1]));
}
} solve(mid+1,r); t1=l;t2=mid+1;
for(i=l;i<=r;i++){
if(t2==r+1||(t1<=mid&&a[t1].x<a[t2].x)) tmp[i]=a[t1++];
else tmp[i]=a[t2++];
}
memcpy(a+l,tmp+l,sizeof(node)*(r-l+1));
}
int main(){
n=read();int i,flag=0,cntq=0;
for(i=1;i<=n;i++){
scanf("%d%lf%lf",&a[i].op,&a[i].x,&a[i].y);
a[i].id=i;
if(a[i].op){
a[i].qid=++cntq;
if(flag) ans[cntq]=1;
if(a[i].y) a[i].k=-a[i].x/a[i].y;
else a[i].k=1e30;
}
else flag=1;
}
sort(a+1,a+n+1,cmp);
solve(1,n);
for(i=1;i<=cntq;i++) puts(ans[i]?"Yes":"No");
}

[BZOJ2961] 共点圆 [cdq分治+凸包]的更多相关文章

  1. BZOJ2961 共点圆[CDQ分治]

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

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

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

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

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

  4. bzoj2961 共点圆 bzoj 4140

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

  5. Bzoj2149拆迁队:cdq分治 凸包

    国际惯例的题面:我们考虑大力DP.首先重新定义代价为:1e13*选择数量-(总高度+总补偿).这样我们只需要一个long long就能维护.然后重新定义高度为heighti - i,这样我们能选择高度 ...

  6. BZOJ2961: 共点圆

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

  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】共点圆 k-d树

    更新:此题我的代码设置eps=1e-8会WA,现在改为1e-9貌似T了 此题网上的大部分做法是cdq分治+凸包,然而我觉得太烦了,于是自己口胡了一个k-d树做法: 加入一个圆$(x,y)$,直接在k- ...

随机推荐

  1. 数据库路由中间件MyCat - 背景篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...

  2. eclipse报这个错误org.eclipse.swt.SWTError: No more handles (eclipse 和 TeamViewer 冲突)

    错误:  org.eclipse.swt.SWTError: No more handles     at org.eclipse.swt.SWT.error(SWT.java:4387)     a ...

  3. beauifulsoup模块的介绍

    01   爬虫基础知识介绍 相关库:1.requests,re  2.BeautifulSoup   3.hackhttp 使用requests发起get,post请求,获取状态码,内容: 使用re匹 ...

  4. Python学习笔记(一)一一一环境安装错误总结

    第三方库安装 1   windows存在多个版本的python,pip安装Python库失败 解决方案:进入对应官网下载安装包,步骤:1 下载安装包到C:\Python36\Lib\site-pack ...

  5. PHP计算两个已知经纬度之间的距离

    /** *求两个已知经纬度之间的距离,单位为千米 *@param lng1,lng2 经度 *@param lat1,lat2 纬度 *@return float 距离,单位千米 **/ privat ...

  6. 【Linux 运维】Centos7初始化网络配置

    设置网络 (1)动态获取一个IP地址 #dhclient        系统自动自动获取一个IP地址#ip addr         查看获取的ip地址(2)查看网关,子网掩码 虚拟机编辑>虚拟 ...

  7. 最小生成树与Prim算法

    最小生成树(MST) 定义 首先是一棵树(废话 其次没有回路(废话 包含全部顶点和V-1条边 边的权重和最小!!!!! 所以如果是单棵最小生成树,至少说明图是连通的.不然就是森林. 生成思路 既然是根 ...

  8. SVM 为什么要从原始问题变为对偶问题来求解

    这个问题困扰了我许久,下面是我搜集整理到的答案 对偶问题将原始问题中的约束转为了对偶问题中的等式约束 方便核函数的引入 改变了问题的复杂度.由求特征向量w转化为求比例系数a,在原始问题下,求解的复杂度 ...

  9. Caching Data in the Architecture (C#)

    http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-in-the-architecture-cs ...

  10. Hero In Maze(BFS广搜)

    Description 500年前,Jesse是我国最卓越的剑客.他英俊潇洒,而且机智过人^_^.突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中.Jesse听说这个消息已经是两天以后了, ...