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- ...
随机推荐
- webpack 4 升级点
webpack 4 升级点: 默认entry为./src,默认output为/dist sideEffects 在webapck2开始支持ESModule后,webpack提出了tree-shakin ...
- react:路由登陆后才能访问的控制
react-router 通过创建一个 需要认证的路由 来限制登陆后才能访问. 官方例子:https://reacttraining.com/react-router/web/example/auth ...
- JFrame背景色设置
JFrame对象本身是包含Pane的,一般我们在往JFrame中添加组件时,都加在了ContentPane中,这个可以通过JFrame的成员方法getContentPane()取出来.所以如果设置JF ...
- RedHat6.5安装Spark集群
版本号: RedHat6.5 RHEL 6.5系统安装配置图解教程(rhel-server-6.5) JDK1.8 http://blog.csdn.net/chongxin1/arti ...
- RedHat6.5安装单机flume1.6
版本号: RedHat6.5 JDK1.8 apache-flume-1.6.0 1.apache-flume-1.6.0-bin.tar.gz 下载 官网下载地址:http://archiv ...
- EXCEL 将网络图片地址插入为锁定的图片单元格宏
Sub InsertPic2(ByVal 图片链接 As String, ByVal 插入图片表名 As String, ByVal 插入图片单元格地址 As String) On Error Res ...
- TextBox限制输入字母、数字、退格键
公共方法如下: /// <summary> /// 正则表达式验证只能输入数字或字母 /// </summary> /// <param name="pendi ...
- 手机与PC的影音相互播放(DLNA/UPNP)
DLNA:全称是DIGITAL LIVING NETWORK ALLIANCE(数字生活网络联盟), 旨在解决个人PC,消费电器,移动设备在内的无线网络和有线网络的互联互通,使得数字媒体和内容服务的无 ...
- 进程守护为什么选择pm2
官网::: https://pm2.io/doc/en/runtime/quick-start/ 前言 源码:https://github.com/Unitech/pm2 这里的pm2并不是大气污染 ...
- [蓝桥杯]ALGO-87.算法训练_字串统计
问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最长的,如果仍然有多个,输出第一次出现最早的. 输入格式 第一行一个 ...