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获取距离某天前或后的日期

    /** * param  Date Object:Mon May 11 13:53:08 UTC+0800 2015  * n 自param 起向后多少天 * return Date Object:M ...

  2. Codeforces Round #441 (Div. 2)【A、B、C、D】

    Codeforces Round #441 (Div. 2) codeforces 876 A. Trip For Meal(水题) 题意:R.O.E三点互连,给出任意两点间距离,你在R点,每次只能去 ...

  3. hook与链表操作

    hook与链表的节点操作有相似之处: 链表的前后顺序相当于程序的执行流: 对链表节点的替换或插入相当于hook技术: 1.替换:用新的节点替换原来的节点: 2.前插入: 3.后插入: 修改原来的结构.

  4. Cookies、sessionStorage和localStorage解释及区别?

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务器端进行数据交互 一.cookie和session Cookie和 session都是用来跟踪浏览 ...

  5. 【webpack】理解配置文件

    学习链接: http://blog.csdn.net/hongchh/article/details/55113751 https://segmentfault.com/a/1190000009356 ...

  6. PDF压缩,在线压缩免费

    https://smallpdf.com/ 一个很牛逼的网站 https://zh.wikihow.com/ https://zh.wikihow.com/%E9%A6%96%E9%A1%B5

  7. 轻量ORM-SqlRepoEx (十四)最佳实践之Dapper(1)

    简介:SqlRepoEx是 .Net平台下兼容.NET Standard 2.0人一个轻型的ORM.解决了Lambda转Sql语句这一难题,SqlRepoEx使用的是Lambda表达式,所以,对c#程 ...

  8. ubuntu下USB口插入USB转TTL查看串口号

    首先先要获取权限 sudo su 然后 cd /devls ls可以列出所有的串口号(确保此时USB转TTL已经插在电脑上了) 然后拔掉USB转TTL 在ls一下列出所有的串口设备 对比可以发现,插上 ...

  9. eclipse的svn插件

    SVN插件下载地址及更新地址,你根据需要选择你需要的版本.现在最新是1.8.xLinks for 1.8.x Release:Eclipse update site URL: http://subcl ...

  10. MySQL常用:Got a packet bigger than 'max_allowed_packet' bytes & MySQL开远程服务

    1. 数据导入时出现错误 Got a packet bigger than 'max_allowed_packet' bytes 通过终端进入mysql控制台 mysql>show VARIAB ...