bzoj2961 共点圆 (CDQ分治, 凸包)
/*
可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它
看看是否是在合法的那一面
然后cdq分治就可以了
代码基本是抄的,
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<cmath>
#define ll long long
#define M 500050
#define mmp make_pair
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
const double inf = pow(2, 80), eps = 1e-10;
int q1[M], q2[M], ans[M], tot, flag, n;
struct Vec {
double x, y;
};
struct Note {
Vec x;
int op, id, qid;
double k;
bool operator < (const Note &b) const {
return this->k < b.k;
}
} e[M], tmp[M];
double sqr(double x) {
return x * x;
}
double slope(Vec a, Vec b) {
if(fabs(a.x - b.x) < eps) return inf;
return (b.y - a.y) / (b.x - a.x);
}
double dis(Vec a, Vec b) {
return sqr(a.x - b.x) + sqr(a.y - b.y);
}
double R(Vec a) {
return sqr(a.x) + sqr(a.y);
}
void cdq(int l, int r) {
if(l == r) return;
int mid = (l + r) >> 1, p1 = l, p2 = mid + 1, h1 = 1, h2 = 1, t1 = 0, t2 = 0;
for(int i = l; i <= r; i++) {
if(e[i].id <= mid) tmp[p1++] = e[i];
else tmp[p2++] = e[i];
}
memcpy(e + l, tmp + l, sizeof(e[0]) * (r - l + 1));
cdq(l, mid);
for(int i = l; i <= mid; i++) {
if(e[i].op) continue;
while(h1 < t1 && slope(e[q1[t1]].x, e[i].x) < slope(e[q1[t1 - 1]].x, e[q1[t1]].x)) t1--;
q1[++t1] = i;
while(h2 < t2 && slope(e[q2[t2]].x, e[i].x) > slope(e[q2[t2 - 1]].x, e[q2[t2]].x)) t2--;
q2[++t2] = i;
}
for(int i = mid + 1; i <= r; i++) {
if(!e[i].op) continue;
if(e[i].x.y > 0) {
while(h1 < t1 && slope(e[q1[h1]].x, e[q1[h1 + 1]].x) < e[i].k) h1++;
if(h1 <= t1 && dis(e[q1[h1]].x, e[i].x) > R(e[q1[h1]].x)) ans[e[i].qid] = 0;
} else {
while(h2 < t2 && slope(e[q2[t2 - 1]].x, e[q2[t2]].x) < e[i].k) t2--;
if(h2 <= t2 && dis(e[q2[t2]].x, e[i].x) > R(e[q2[t2]].x)) ans[e[i].qid] = 0;
}
}
cdq(mid + 1, r);
p1 = l, p2 = mid + 1;
for(int i = l; i <= r; i++) {
if(p2 > r || p1 <= mid && e[p1].x.x < e[p2].x.x) tmp[i] = e[p1++];
else tmp[i] = e[p2++];
}
memcpy(e + l, tmp + l, sizeof(e[0]) * (r - l + 1));
}
int main() {
n = read();
for(int i = 1; i <= n; i++) {
e[i].op = read();
scanf("%lf%lf", &e[i].x.x, &e[i].x.y);
e[i].id = i;
if(e[i].op) {
e[i].qid = ++tot;
if(flag) ans[tot] = 1;
if(e[i].x.y) e[i].k = -e[i].x.x / e[i].x.y;
else e[i].k = inf;
} else flag = 1;
}
sort(e + 1, e + n + 1);
cdq(1, n);
for(int i = 1; i <= tot; i++) 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分治+凸包)
题面 传送门 题解 这题解法真是多啊--据说可以圆反演转化为动态插入半平面并判断给定点是否在半平面交中,或者化一下改成给定点判断是否所有点都在某一个半平面内-- 鉴于圆反演我也不会,这里讲一下直接推的 ...
- bzoj2961 共点圆 bzoj 4140
题解: 比较水的一道题 首先我们化简一下式子发现是维护xxo+yyo的最值 显然是用凸包来做 我们可以直接用支持插入删除的凸包 也是nlogn的 因为没有强制在线,我们也可以cdq,考虑前面一半对答案 ...
- Bzoj2149拆迁队:cdq分治 凸包
国际惯例的题面:我们考虑大力DP.首先重新定义代价为:1e13*选择数量-(总高度+总补偿).这样我们只需要一个long long就能维护.然后重新定义高度为heighti - i,这样我们能选择高度 ...
- BZOJ2961: 共点圆
好久没发了 CDQ分治,具体做法见XHR的论文… /************************************************************** Problem: 29 ...
- [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】共点圆 k-d树
更新:此题我的代码设置eps=1e-8会WA,现在改为1e-9貌似T了 此题网上的大部分做法是cdq分治+凸包,然而我觉得太烦了,于是自己口胡了一个k-d树做法: 加入一个圆$(x,y)$,直接在k- ...
随机推荐
- 用actor model实现intel tbb这样的用法
关于什么事actor model,什么事intel tbb这样的用法我就不详细说了,具体请上网查文档 class MyActor { F f; MyActor inputs[]; MyActor ou ...
- Jmeter学习—004—使用代理录制脚本—HTTP代理服务器(APP、web皆可)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mmmmmmm_2niu/article/details/78136253记得我最开始使用jmeter ...
- IDEA中使用springBoot+gradle构建多模块项目
https://blog.csdn.net/forMelo/article/details/78995875
- Linux下安装uci
Compiling UCI as stand alone cd ~ git clone git://nbd.name/uci.git ~/uci cd ~/uci cmake -DBUILD_LUA= ...
- Ubuntu PPA软件源
PPA,其英文全称为 Personal Package Archives,即个人软件包档案.是 Ubuntu Launchpad 网站提供的一项源服务,允许个人用户上传软件源代码,通过 Launchp ...
- 【Mysql】mysql使用触发器创建hash索引
概述 若设计的数据表中,包含较长的字段,比如URL(通常都会比较长),查询时需要根据该字段进行过滤: select * from table_xxx where url = 'xxxxxxx'; 为了 ...
- C++标准模板库(STL)介绍:set的基本用法
1.元素的方向遍历 使用反向迭代器reverse_iterator可以反向遍历集合,输出集合元素的反向排序结果.它需要用到rbegin()和rend()两个方法,它们分别给出了反向遍历的开始位置和结束 ...
- 使用R语言-计算均值,方差等
R语言对于数值计算很方便,最近用到了计算方差,标准差的功能,特记录. 数据准备 height <- c(6.00, 5.92, 5.58, 5.92) 1 计算均值 mean(height) [ ...
- Mongodb条件查询Query的用法
Query.All("name", "a", "b");//通过多个元素来匹配数组Query.And(Query.EQ("name ...
- 服务容错保护断路器Hystrix之四:断路器监控(Hystrix Dashboard)-turbine集群监控
turbine 英[ˈtɜ:baɪn] n. 汽轮机; 涡轮机; 透平机; OK,上文我们看了一个监控单体应用的例子,在实际应用中,我们要监控的应用往往是一个集群,这个时候我们就得采取Turbine集 ...