http://www.lydsy.com/JudgeOnline/problem.php?id=2961 (题目链接)

题意

  按照一定的顺序给出一些圆和一些点,对于每一个点问是否在所有圆内。

Solution

  我算是明白计算几何题是有多蛋疼了。

  圆包含点$(x_0,y_0)$的条件:$$x*x+y*y>=(x-x_0)*(x-x_0)+(y-y_0)*(y-y_0)$$

$$-2x_0+x_0^2+y_0^2<=2y_0y$$

  题目只说圆心的纵坐标大于$0$,气的我吐出一口老血。所以根据$y_0$的正负,分类讨论,每种情况都是一个半平面,直线的斜率为$-x_0/y_0$,然后我们维护一个上凸包和一个下凸包对询问进行更新,CDQ分治求解就可以了。

细节

  各种细节蛋疼死了,横坐标相等斜率特判,而且是有向线段的斜率两个点的顺序不能乱写。一开始还把斜截式写成了一般式搞了半天我就说怎么不对。

代码

// bzoj2961
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define LD long double
#define inf 1e40
#define eps 1e-10
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std; const int maxn=500010;
int n,qu[maxn],st[maxn],ans[maxn];
struct data {LD x,y,k;int op,id;}q[maxn],nq[maxn]; bool cmpk(data a,data b) {return a.k<b.k;}
bool cmpid(data a,data b) {return a.id<b.id;}
LD slope(data a,data b) {
return fabs(a.x-b.x)<=eps ? inf*(a.y<b.y ? 1 : -1) : (b.y-a.y)/(b.x-a.x); //mdzz一定要写a.y<b.y而不是a.y>b.y,有向线段
}
LD dis(int x,int y) {
return (q[x].x-q[y].x)*(q[x].x-q[y].x)+(q[x].y-q[y].y)*(q[x].y-q[y].y);
}
void solve(int l,int r) {
if (l==r) return;
int mid=(l+r)>>1,l1=l,l2=mid+1,top=0,h=1,t=0;
for (int i=l;i<=r;i++) q[i].id<=mid ? nq[l1++]=q[i] : nq[l2++]=q[i];
for (int i=l;i<=r;i++) q[i]=nq[i];
solve(l,mid);
for (int i=l;i<=mid;i++) if (!q[i].op) {
while (top>1 && slope(q[st[top-1]],q[st[top]])<slope(q[st[top]],q[i])+eps) top--;
st[++top]=i;
while (h<t && slope(q[qu[t-1]],q[qu[t]])>slope(q[qu[t]],q[i])-eps) t--;
qu[++t]=i;
}
for (int i=mid+1;i<=r;i++) if (q[i].op) {
if (q[i].y<0) {
while (top>1 && slope(q[st[top-1]],q[st[top]])<q[i].k) top--;
if (top) ans[q[i].id]&=(dis(i,st[top])<=dis(st[top],0)+eps); //判断条件一定要加
}
else {
while (h<t && slope(q[qu[h]],q[qu[h+1]])<q[i].k) h++;
if (h<=t) ans[q[i].id]&=(dis(i,qu[h])<=dis(qu[h],0)+eps); //判断条件一定要加
}
}
solve(mid+1,r);
for (int i=l,j=mid+1,k=l;i<=mid || j<=r;) {
if (j>r || (i<=mid && q[i].x<q[j].x)) nq[k++]=q[i++];
else nq[k++]=q[j++];
}
for (int i=l;i<=r;i++) q[i]=nq[i];
}
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d%Lf%Lf",&q[i].op,&q[i].x,&q[i].y);
if (q[i].op) q[i].k=-q[i].x/q[i].y;
ans[i]=1;q[i].id=i;
}
sort(q+1,q+1+n,cmpk);
solve(1,n);
sort(q+1,q+1+n,cmpid);
for (int flag=0,i=1;i<=n;i++) {
if (q[i].op) puts(flag && ans[q[i].id] ? "Yes" : "No");
else flag=1;
}
return 0;
}

【bzoj2961】 共点圆的更多相关文章

  1. BZOJ2961: 共点圆

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

  2. BZOJ2961 共点圆[CDQ分治]

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

  3. bzoj2961 共点圆 bzoj 4140

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. # 2017-2018-2 20155231《网络对抗技术》实验九: Web安全基础实践

    2017-2018-2 20155231<网络对抗技术>实验九: Web安全基础实践 实验要求: 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验内容: ( ...

  2. 20155321 《网络对抗》 Exp6 信息搜集与漏洞扫描

    20155321 <网络对抗> Exp6 信息搜集与漏洞扫描 实验内容 信息搜集 whois 在kali终端输入whois 网址,查看注册的公司.服务.注册省份.传真.电话等信息 dig或 ...

  3. Hibernate一对多关联关系保存时的探究

    在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功.    因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备         这里有一点提前 ...

  4. vijos 1641 Vs Snowy

    代码: #include<set> #include<cstdio> #include<cstring> #include<iostream> #inc ...

  5. [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]

    题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...

  6. Security6:查看授予的权限

    在SQL Server的安全体系中,权限分为服务器级别(Server-Level)和数据库级别(Database-Level),用户的权限分为两种形式,分别是直接授予的权限,以及由于加入角色而获得的权 ...

  7. CSS快速入门-属性和伪类

    一.属性选择器 <div class="gradefather"> hello1 <div name="son">hello2 < ...

  8. BaseProxy:异步http/https中间人

    BaseProxy 异步http/https代理,可拦截并修改报文,可以作为中间人工具.仅支持py3.5+.项目地址:BaseProxy. 意义 BaseProxy项目的本意是为了使HTTP/HTTP ...

  9. 【DDD】业务建模实践 —— 发布帖子

    本文是基于上一篇‘业务建模战术’的实践,主要讲解‘发表帖子’场景的业务建模,包括:业务建模.业务模型.示例代码:示例代码会使用java编写,文末附有github地址.相比于<领域驱动设计> ...

  10. 区块链--Bitcoin共识机制

    目录 中心化和去中心化 比特币共识机制 拜占庭将军共识机制 比特币成功解决了拜占庭问题 中心化和去中心化 中心化模式: 优点:效率高 缺点:中间层次太多(组织层次连接) 去中心化模式: 缺点:效率低 ...