【BZOJ2961】共点圆(CDQ分治)
【BZOJ2961】共点圆(CDQ分治)
题面
题解
设询问点\((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分治)的更多相关文章
- [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_ ...
- BZOJ2961 共点圆[CDQ分治]
题面 bzoj 其实就是推一下圆的式子 长成这个样子 假设要查询的点是(x, y) 某个圆心是(p, q) \((x - p)^2 + (y - q)^2 \leq p^2 + q^2\) 变成 \( ...
- bzoj2961 共点圆 (CDQ分治, 凸包)
/* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面 然后cdq分治就可以了 代码基本是抄的, */ #inc ...
- BZOJ2961: 共点圆(CDQ分治+凸包)
题面 传送门 题解 这题解法真是多啊--据说可以圆反演转化为动态插入半平面并判断给定点是否在半平面交中,或者化一下改成给定点判断是否所有点都在某一个半平面内-- 鉴于圆反演我也不会,这里讲一下直接推的 ...
- BZOJ2961: 共点圆
好久没发了 CDQ分治,具体做法见XHR的论文… /************************************************************** Problem: 29 ...
- bzoj2961 共点圆 bzoj 4140
题解: 比较水的一道题 首先我们化简一下式子发现是维护xxo+yyo的最值 显然是用凸包来做 我们可以直接用支持插入删除的凸包 也是nlogn的 因为没有强制在线,我们也可以cdq,考虑前面一半对答案 ...
- [BZOJ2961]共点圆-[凸包+cdq分治]
Description 传送门 Solution 考虑对于每一个点: 设圆的坐标为(x,y),点的坐标为(x0,y0).依题意得,当一个点在圆里,需要满足(x-x0)2+(y-y0)2<=x2+ ...
- bzoj 2961 共点圆 cdq+凸包+三分
题目大意 两种操作 1)插入一个过原点的圆 2)询问一个点是否在所有的圆中 分析 在圆中则在半径范围内 设圆心 \(x,y\) 查询点\(x_0,y_0\) 则\(\sqrt{(x-x_0)^2+(y ...
- 【bzoj2961】 共点圆
http://www.lydsy.com/JudgeOnline/problem.php?id=2961 (题目链接) 题意 按照一定的顺序给出一些圆和一些点,对于每一个点问是否在所有圆内. Solu ...
随机推荐
- [Processing] 弹球
PVector localPos = new PVector(0,0);//起始位置 PVector velocity;//速度方向 float speed = 20;//速度大小 void setu ...
- linux常用命令总结(含选项参数)
• 用户切换 su 切换到root用户并不切换环境 su - root 切换到root用户并切换环境 su redhat 切换到redhat不切换环境 • cd切换目 ...
- zabbix切换中文,监控图下方显示乱码,监控图X轴不显示时间问题解决(适用于所有版本)
一.现象: abbix3.4安装好后添加zabbix图形,发现有好多方块 这是因为zabbix web程序缺少中文字体 二.解决方案1: 1.在windows系统找一个中文字体上传到服务器中,我这里找 ...
- Vue+webpack项目中,运行报错Cannot find module 'chalk'的处理
刚开始用vue + webpack新建项目,在github上下载了一个示例,输入npm init >>>npm run dev 后报错 Cannot find module 'cha ...
- 硬件设计原理图Checklist 参考案例二 【转载】
类别 描述 检视规则 原理图需要进行检视,提交集体检视是需要完成自检,确保没有低级问题. 检视规则 原理图要和公司团队和可以邀请的专家一起进行检视. 检视规则 第一次原理图发出进行集体检视后所有的修改 ...
- Task 4.5 求二维数组中的最大连通子数组之和
任务:输入一个二维整形数组,数组里有正数也有负数. 求所有子数组的和的最大值.要求时间复杂度为O(n). 1.设计思想:因为用之前的解决子数组最大和的问题的思路一直没能解决这个问题,后来看到同学使用将 ...
- flownet2.0 caffe anaconda2 编译安装
1. 下载flownet2.0源码到指定目录 cd /home/zzq/saliency_models/deep_optical_flow git clone https://github.com/l ...
- 结对随即四则运算(带界面Java版)
//随机四则运算类 public class 随机四则运算 { public static void main(String[] args) { new 界面();//进入随机四则运算的首界面 } } ...
- 【搜索】POJ-3009 DFS+回溯
一.题目 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. B ...
- 电梯调度系统(界面由C图形库编绘)
电梯调度系统编程 1.编程题目 电梯调度. 2.结对编程组员 黄冠译,刘畅. 3.编程语言 C语言图形库. 4.题目要求: 5.代码运行及结果调试: ① 运行界面为C++图形库支持,开始运行的初始界面 ...