[BZOJ2961]共点圆-[凸包+cdq分治]
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分治]的更多相关文章
- BZOJ2961: 共点圆(CDQ分治+凸包)
题面 传送门 题解 这题解法真是多啊--据说可以圆反演转化为动态插入半平面并判断给定点是否在半平面交中,或者化一下改成给定点判断是否所有点都在某一个半平面内-- 鉴于圆反演我也不会,这里讲一下直接推的 ...
- bzoj2961 共点圆 (CDQ分治, 凸包)
/* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面 然后cdq分治就可以了 代码基本是抄的, */ #inc ...
- 【BZOJ2961】共点圆(CDQ分治)
[BZOJ2961]共点圆(CDQ分治) 题面 BZOJ 题解 设询问点\((x,y)\),圆心是\((X,Y)\) 那么如果点在园内的话就需要满足 \((X-x)^2+(Y-y)^2\le X^2+ ...
- [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 共点圆 bzoj 4140
题解: 比较水的一道题 首先我们化简一下式子发现是维护xxo+yyo的最值 显然是用凸包来做 我们可以直接用支持插入删除的凸包 也是nlogn的 因为没有强制在线,我们也可以cdq,考虑前面一半对答案 ...
- BZOJ2961: 共点圆
好久没发了 CDQ分治,具体做法见XHR的论文… /************************************************************** Problem: 29 ...
- 【bzoj2961】 共点圆
http://www.lydsy.com/JudgeOnline/problem.php?id=2961 (题目链接) 题意 按照一定的顺序给出一些圆和一些点,对于每一个点问是否在所有圆内. Solu ...
- Bzoj2149拆迁队:cdq分治 凸包
国际惯例的题面:我们考虑大力DP.首先重新定义代价为:1e13*选择数量-(总高度+总补偿).这样我们只需要一个long long就能维护.然后重新定义高度为heighti - i,这样我们能选择高度 ...
随机推荐
- java中JVM的原理重温【转】
一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...
- 查看linux上面是否有安装redis,redis启动
1.检测是否有安装redis-cli和redis-server; [root@localhost bin]# whereis redis-cli redis-cli: /usr/bin/redis-c ...
- python中基于descriptor的一些概念(下)
@python中基于descriptor的一些概念(下) 3. Descriptor介绍 3.1 Descriptor代码示例 3.2 定义 3.3 Descriptor Protocol(协议) 3 ...
- Cordova Android源代码分析系列一(项目总览和CordovaActivity分析)
版权声明:本文为博主offbye西涛原创文章.未经博主同意不得转载. https://blog.csdn.net/offbye/article/details/31776833 PhoneGap/Co ...
- Django中模型(一)
Django中模型(一) 一. 基本开发流程 1. 配置数据库 2. 定义模型类:一个模型类都在数据库中对应一张数据表 3. 生成迁移文件 4. ...
- php filesize() 方法返回的文件大小异常
问题描述:需要生成一个 700k 大小左右的文件,相关代码如下: <?php $handle = fopen('./split.log', 'a+'); $result = 0; while( ...
- js 键盘点击事件
回车键(Enter)的触发事件 js 代码如下: document.onkeydown = function (e) { if (!e) e = window.event; if ((e.keyCo ...
- Spring(十四)之事务
事务管理 一个数据库事务是一个被视为单一的工作单元的操作序列.这些操作应该要么完整地执行,要么完全不执行.事务管理是一个重要组成部分,RDBMS 面向企业应用程序,以确保数据完整性和一致性.事务的概念 ...
- oracle中的greatest 函数和 least函数
oracle中的greatest 函数和 least函数 原文地址:https://blog.csdn.net/sinat_32023305/article/details/78778596 g ...
- Xcode缓存数据清除
1. 移除 APP 打包的ipa历史版本(Archives) 不可恢复,就是你打的包,如果需要dysm文件,及时备份 路径:~/Library/Developer/Xcode/Archives 2. ...