BZOJ5465: [APIO 2018] 选圆圈(K-D Tree)
题意
Sol
下面是错误做法,正解请看这里
考虑直接用K-D tree模拟。。
刚开始想的是维护矩形最大最小值,以及子树中最大圆的位置,然后。。。

实际上最大圆的位置是不用维护的,直接把原序列排一遍序就可以了
再努力卡卡常就过了
如果还过不了的话可以尝试把所有点都转一个角度
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define chmin(x, y) (x = x < y ? x : y)
#define chmax(x, y) (x = x > y ? x : y)
#define ls(x) T[k].ls
#define rs(x) T[k].rs
#define double long double
const double alpha(acos(-1) / 5);
const double cosa(cos(alpha));
const double sina(sin(alpha));
using namespace std;
const int MAXN = 1e6 + 10;
const double INF = 1e12 + 10, eps = 1e-11;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, WD, root, tot, num, ans[MAXN];
struct Point {
double x[2], r;
int id;
bool operator < (const Point &rhs) const {
return rhs.x[WD] - x[WD] > eps;
}
double operator [] (const int d) {
return x[d];
}
}P[MAXN];
int comp(const Point &a, const Point b) {
return a.r == b.r ? a.id < b.id : a.r > b.r;
}
struct Node {
int ls, rs, id;
double mx[2], mi[2];
Point p;
}T[MAXN];
void update(int k) {
for(int i = 0; i <= 1; i++) {
if(!ans[T[k].id]) T[k].mi[i] = T[k].p[i] - T[k].p.r, T[k].mx[i] = T[k].p[i] + T[k].p.r;
else T[k].mi[i] = INF, T[k].mx[i] = -INF;
if(ls(k)) chmin(T[k].mi[i], T[ls(k)].mi[i]), chmax(T[k].mx[i], T[ls(k)].mx[i]);
if(rs(k)) chmin(T[k].mi[i], T[rs(k)].mi[i]), chmax(T[k].mx[i], T[rs(k)].mx[i]);
}
}
int Build(int l, int r, int wd) {
if(l > r) return 0;
WD = wd; int mid = (l + r) >> 1, k = ++tot;
nth_element(P + l, P + mid, P + r + 1);
T[k].p = P[mid]; T[k].id = P[mid].id;
T[k].ls = Build(l, mid - 1, wd ^ 1) ;
T[k].rs = Build(mid + 1, r, wd ^ 1);
update(k);
return k;
}
double sqr(double x) {
return x * x;
}
bool judge(Point a, Point b) {
double tmp = sqr(a[0] - b[0]) + sqr(a[1] - b[1]);
return sqr(a.r + b.r) + eps - tmp > 0;
}
bool pd(int k, Point a) {
for(int i = 0; i <= 1; i++)
if((a[i] + a.r + eps < T[k].mi[i]) || (a[i] - a.r - eps > T[k].mx[i])) return 1;
return 0;
}
void Delet(int k, Point a) {
if(pd(k, a)) return ;
if(!ans[T[k].id] && judge(T[k].p, a)) ans[T[k].id] = a.id, T[k].p.r = -INF, num++;
if(ls(k)) Delet(ls(k), a);
if(rs(k)) Delet(rs(k), a);
update(k);
}
int main() {
//freopen("a.in", "r", stdin);
N = read();
for(int i = 1; i <= N; i++) {
double x = read(), y = read(), tx = x * cosa - y * sina, ty = x * sina + y * cosa;
P[i].x[0] = x; P[i].x[1] = y; P[i].r = read(), P[i].id = i;
}
root = Build(1, N, 0);
sort(P + 1, P + N + 1, comp);
for(int i = 1; i <= N; i++) if(!ans[P[i].id]) Delet(root, P[i]);
for(int i = 1; i <= N; i++) printf("%d ", ans[i]);
return 0;
}
BZOJ5465: [APIO 2018] 选圆圈(K-D Tree)的更多相关文章
- BZOJ5465 : [APIO 2018] 选圆圈
假设最大的圆半径为$R$,以$2R$为大小将地图划分为一个个格子,那么每个圆只需要检查圆心在附近$9$个格子内部的所有圆. 在当前圆的半径不足$\frac{R}{2}$时重构网格,那么最多重构$O(\ ...
- APIO 2018选圆圈
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #i ...
- 「APIO2018选圆圈」
「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...
- 学习笔记--APIO 2018 二分专题 By wuvin
前言: 在APIO 2018 Day2下午听wuvin讲二分,听了一上午的神仙,现在终于有可以听懂了. 专题: 平均边权最大 题目链接:https://www.questoj.cn/problem/3 ...
- 【APIO2018】选圆圈(平面分块 | CDQ分治 | KDT)
Description 给定平面上的 \(n\) 个圆,用三个参数 \((x, y, R)\) 表示圆心坐标和半径. 每次选取最大的一个尚未被删除的圆删除,并同时删除所有与其相切或相交的圆. 最后输出 ...
- 【LG4631】[APIO2018]Circle selection 选圆圈
[LG4631][APIO2018]Circle selection 选圆圈 题面 洛谷 题解 用\(kdt\)乱搞剪枝. 维护每个圆在\(x.y\)轴的坐标范围 相当于维护一个矩形的坐标范围为\([ ...
- BZOJ5465 APIO2018选圆圈(KD-Tree+堆)
考虑乱搞,用矩形框圆放KD-Tree上,如果当前删除的圆和矩形有交就递归下去删.为防止被卡,将坐标系旋转一定角度即可.注意eps稍微设大一点,最好开上long double. #include< ...
- [BZOJ5465][APIO2018]选圆圈(KD-Tree)
题意:给你n个圆,每次选择半径最大的,将它和与它相交的圆全部删去,输出每个圆是在哪次被删的. KD树模板题.用一个矩形框住这个圆,就可以直接剪枝了.为了防止被卡可以将点旋转一个角度,为了保险还可以多转 ...
- 【LOJ】#2586. 「APIO2018」选圆圈
题解 不旋转坐标系,TLE,旋转坐标系,最慢一个点0.5s--maya,出题人数据水平很高了-- 好吧,如果你不旋转坐标系,写一个正确性和复杂度未知的K - D树,没有优化,你可以得到87分的好成绩 ...
随机推荐
- java爬虫中jsoup的使用
jsoup可以用来解析HTML的内容,其功能非常强大,它可以向javascript那样直接从网页中提取有用的信息 例如1: 从html字符串中解析数据 //直接从字符串中获取 public stati ...
- Linux系统NAT模式下设置网络网关
1.配置Vm网络编辑器 2.配置固定IP地址 命令:vi /etc/sysconfig/network-scripts/ifcfg-ens33 #下面内容直接复制进去,如果有重复的可以去除 TYPE= ...
- django文章收藏
http://www.cnblogs.com/suoning/p/5818869.html
- C++默认实参
某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同的值,此时,我们把这个反复出现的值称为函数的默认实参.调用含有默认实参的函数时,可以包含该实参,也可以省略该实参. 例如定义一个函数sc ...
- net 反编译神器
文章地址:https://www.cnblogs.com/sheng-jie/p/10168411.html dnSpy官网下载 分享链接 .net core源码导航 https://www.cnb ...
- 【笔记】AJAX基础
[笔记]AJAX基础 Django AJAX 知识储备:JSON 什么是 JSON JSON 是轻量级的文本数据交换格式 JSON 独立于语言和平台.JSON 解析器和 JSON 库支持许多不同的编 ...
- github里如何删除一个repository仓库
高手请绕行,新手往下走. 作为一个刚接触github(https://github.com/)的新手,除了感叹开源的丰富和强大之外,自己肯定也想试用一下,因此申请帐号神马的.今天自己创建一个Repos ...
- pull强制覆盖本地
今天我总结的是在项目中经常用到的Git命令,上传和下拉文件. 当然在进行上传和下拉操作之前,你首先要做的就是将本地和Git库连接起来. 连接命令: git remote add origin + 你G ...
- 【文档】七、Mysql Binlog不同事件类型的事件内容
下面主要讲述了每个类型的事件中的固定和可变部分的数据. Start_log_event_v3/START_EVENT_V3 这个事件出现在v1或v3的binlog文件的开头部分.对于4.0和4.1版本 ...
- Jquery动画操作的stop()函数
今天做一个点击动画时,遇到了当快速连续点击时,动画效果会乱,并不是我们想要达到的效果. 查询了一下,确认是动画累积的原因.网上搜了一下,发现jquery 的stop()函数刚好能解决. stop(cl ...