Description

传送门

Solution

考虑对于每一个点:

设圆的坐标为(x,y),点的坐标为(x0,y0)。依题意得,当一个点在圆里,需要满足(x-x0)2+(y-y0)2<=x2+y2

化简得x02+y02<=2x0*x+2y0*y。

当y0>0,x*(-x0/y0)+0.5y0+x02/(2*y0)<=y,这是一个半平面的式子;当y0<0时同理,但是要变号。

所以对于某个点(x0,y0),我们构造出在它前面所有圆心的凸包。凸包应分为上下。

通过以上式子我们可以得出,当y0>0时应在下凸包上找点(x,y)【该点为直线y=-x0/y0与下凸包的切点,即若此点满足要求,其他任何点都会满足要求。通过这个条件,我们也可以理解把该点理解为2x0*x+2y0*y最小的点】,反之则应该在上凸包上找。

好的让我们假设目前的y0>0,由于凸包上的点(x,y)是按极角排序,x*x0+y*y0是单峰的(这个式子是向量的点乘,其几何意义为:向量a点乘向量b=向量a的长度*向量b的长度*cos(向量a,b的夹角)。所以根据这个定义,证明,就画图吧。qaq正儿八经公式太麻烦了。)上凸包也是一样的。

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps=1e-;
int n;
bool ans[];
struct W{
int tp;double x,y;
friend double operator *(W a,W b){return a.x*b.y-a.y*b.x;}
friend double operator ^(W a,W b){return a.x*b.x+a.y*b.y;}
friend W operator -(W a,W b){return W{,a.x-b.x,a.y-b.y};}
friend bool operator <(W a,W b){return (fabs(a.x-b.x)<eps)?a.y<b.y:a.x<b.x;}
}w[],t[],st[][];//st[0]-上凸包,st[1]-下凸包
double ask(W a,W b){return a.x*b.x+a.y*b.y;}
bool _ok[];
int top0,top1;
bool query(int id)
{
int l,r,mid1,mid2;double minn=1e12;
if (w[id].y<)
{
l=;r=top0;
while (r-l>)
{
mid1=(l*+r)/;mid2=(r*+l)/;
if ((w[id]^st[][mid1])<(w[id]^st[][mid2])) r=mid2;
else l=mid1;
}
for (int i=l;i<=r;i++) minn=min(minn,w[id]^st[][i]); } else
{
l=;r=top1;
while (r-l>)
{
mid1=(l*+r)/;mid2=(r*+l)/;
if ((w[id]^st[][mid1])<(w[id]^st[][mid2])) r=mid2;
else l=mid1;
}
for (int i=l;i<=r;i++) minn=min(minn,w[id]^st[][i]);
}
if (*minn-(w[id].x*w[id].x+w[id].y*w[id].y)<eps) ans[id]=; }
void solve(int l,int r)
{
if (l==r) return;
int mid=(l+r)/,tot=;
solve(l,mid);
solve(mid+,r);
for (int i=l;i<=mid;i++) if (!w[i].tp) t[++tot]=w[i];
sort(t+,t+tot+);
top1=,top0=;
for (int i=;i<=tot;i++)
{
while (top0>&&(st[][top0]-st[][top0-])*(t[i]-st[][top0])>-eps) top0--;
st[][++top0]=t[i];
}
st[][top0+].x=st[][top0].x;st[][top0+].y=-1e12;
for (int i=tot;i;i--)
{
while (top1>&&(st[][top1]-st[][top1-])*(t[i]-st[][top1])>-eps) top1--;
st[][++top1]=t[i];
}
st[][top1+].x=st[][top1].x;st[][top1+].y=1e12;
for (int i=mid+;i<=r;i++) if (w[i].tp&&ans[i]) query(i);
}
bool _is=;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d%lf%lf",&w[i].tp,&w[i].x,&w[i].y);
if (!w[i].tp) _is=;else ans[i]=_is;
}
solve(,n);
for (int i=;i<=n;i++) if (w[i].tp)
if (ans[i]) printf("Yes\n");else printf("No\n");
}

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

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

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

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

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

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

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

  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分治]

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

  6. bzoj2961 共点圆 bzoj 4140

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

  7. BZOJ2961: 共点圆

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

  8. 【bzoj2961】 共点圆

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

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

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

随机推荐

  1. JavaScript的事件对象_滚轮事件

    用户在使用键盘时会触发键盘事件.“DOM2 级事件”最初规定了键盘事件,结果又删除了相应的内容.最终还是使用最初的键盘事件,不过 IE9 已经率先支持“DOM3”级键盘事件. 一.键码 在发生 key ...

  2. webpack中热模块更新

    Hot Module Replacement,热模块更新,很多时候会简写成HMR. "scripts": { "start": "webpack-de ...

  3. UVA529 Addition Chains

    嘟嘟嘟 还是\(IDA*\). 这道题是\(ZOJ\)的加强版,\(n\)从\(100\)扩大到了\(10000\),所以必须有非常给力的剪枝才能过. 除了迭代加深,还要加上估价函数:对于当前数\(x ...

  4. 20165302 学习基础和C语言基础调查

    学习基础和C语言基础调查 ====== 一,技能学习经验体会 要问我有什么技能比大多数人强,这个我还真的不敢说,虽然我在很多方面都有自己的一些了解,比如乐器和绘画,但也都是一知半解,并没有在某一方面出 ...

  5. QTP基本方法3-----截屏

    1.桌面截屏 Desktop.captureBitMap  path[,bolean] path:保存路径,可选择绝对路径或相对路径 相对路径是保存在脚本保存的目录下编号最大的res目录下. bole ...

  6. 在Ubuntu 18.04中安装Oracle Java JDK 8

    Webupd8 Team维护一个PPA存储库,其中包含适用于所有当前Ubuntu版本的Oracle Java 8安装程序脚本. 1.打开终端并运行命令添加PPA: sudo add-apt-repos ...

  7. Gradle Goodness: Excluding Tasks for Execution

    In Gradle we can create dependencies between tasks. But we can also exclude certain tasks from those ...

  8. 前端基础-HTML的的标签详解

    阅读目录 一.head内常用标签 二. HTML语义化 三. 字符实体 四. h系列标签 五. p标签 六. img标签 七. a标签 八. 列表标签 九. table标签 十. form标签 一. ...

  9. oracle中查看一张表是否有主键,主键在哪个字段上

    利用Oracle中系统自带的两个视图可以实现查看表中主键信息,语句如下:select a.constraint_name, a.column_name from user_cons_columns a ...

  10. 『ACM C++』 PTA 天梯赛练习集L1 | 018-020

    终于一周有这么一天能够安静下来好好学习打打题,还是很美滋滋的哈哈~加油加油~ ------------------------------------------------L1-018------- ...