题面

自己去\(LOJ\)上找

Sol

直接排序然后\(KDTree\)查询

然后发现\(TLE\)了

然后把点旋转一下,就过了。。

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} const int maxn(3e5 + 5);
const double eps(1e-3);
const double alpha(acos(-1) / 5);
const double cosa(cos(alpha));
const double sina(sin(alpha)); int n, ans[maxn], op, rt; struct Data{
double d[2], r;
int id; IL int operator <(RG Data b) const{
return d[op] < b.d[op];
}
} a[maxn]; IL int Cmp(RG Data x, RG Data y){
return x.r != y.r ? x.r > y.r : x.id < y.id;
} struct KDTree{
double d[2], mn[2], mx[2], r;
int ls, rs, id;
} tr[maxn]; IL void Chkmax(RG double &x, RG double y){
if(y > x) x = y;
} IL void Chkmin(RG double &x, RG double y){
if(y < x) x = y;
} IL void Update(RG int x){
tr[x].mn[0] = tr[x].mx[0] = tr[x].d[0];
tr[x].mn[1] = tr[x].mx[1] = tr[x].d[1];
RG int ls = tr[x].ls, rs = tr[x].rs;
if(ls){
Chkmin(tr[x].mn[0], tr[ls].mn[0]), Chkmin(tr[x].mn[1], tr[ls].mn[1]);
Chkmax(tr[x].mx[0], tr[ls].mx[0]), Chkmax(tr[x].mx[1], tr[ls].mx[1]);
}
if(rs){
Chkmin(tr[x].mn[0], tr[rs].mn[0]), Chkmin(tr[x].mn[1], tr[rs].mn[1]);
Chkmax(tr[x].mx[0], tr[rs].mx[0]), Chkmax(tr[x].mx[1], tr[rs].mx[1]);
}
} IL int Build(RG int l, RG int r, RG int nop){
RG int x = (l + r) >> 1; op = nop;
nth_element(a + l, a + x, a + r + 1);
tr[x].d[0] = a[x].d[0], tr[x].d[1] = a[x].d[1];
tr[x].id = a[x].id, tr[x].r = a[x].r;
if(l < x) tr[x].ls = Build(l, x - 1, nop ^ 1);
if(r > x) tr[x].rs = Build(x + 1, r, nop ^ 1);
Update(x);
return x;
} # define Sqr(x) ((x) * (x)) IL int Check(RG int x, RG Data p){
RG double x1 = tr[x].d[0], y1 = tr[x].d[1], x2 = p.d[0], y2 = p.d[1], r1 = tr[x].r, r2 = p.r;
return Sqr(x1 - x2) + Sqr(y1 - y2) - eps <= Sqr(r1 + r2);
} IL int Cut(RG int x, RG Data p){
RG double x2 = p.d[0], y2 = p.d[1], r = p.r + p.r;
if(x2 + r + eps < tr[x].mn[0]) return 1;
if(y2 + r + eps < tr[x].mn[1]) return 1;
if(x2 - r > tr[x].mx[0] + eps) return 1;
if(y2 - r > tr[x].mx[1] + eps) return 1;
return 0;
} IL void Modify(RG int x, RG Data p){
if(Cut(x, p)) return;
if(!ans[tr[x].id] && Check(x, p)) ans[tr[x].id] = p.id;
if(tr[x].ls) Modify(tr[x].ls, p);
if(tr[x].rs) Modify(tr[x].rs, p);
} int main(){
n = Input();
for(RG int i = 1; i <= n; ++i){
RG double x = Input(), y = Input(), r = Input();
a[i] = (Data){x * cosa - y * sina, x * sina + y * cosa, r, i};
}
rt = Build(1, n, 0), sort(a + 1, a + n + 1, Cmp);
for(RG int i = 1; i <= n; ++i)
if(!ans[a[i].id]) Modify(rt, a[i]);
for(RG int i = 1; i <= n; ++i) printf("%d ", ans[i]);
return 0;
}

[APIO2018] Circle selection 选圆圈(假题解)的更多相关文章

  1. 【LG4631】[APIO2018]Circle selection 选圆圈

    [LG4631][APIO2018]Circle selection 选圆圈 题面 洛谷 题解 用\(kdt\)乱搞剪枝. 维护每个圆在\(x.y\)轴的坐标范围 相当于维护一个矩形的坐标范围为\([ ...

  2. [Luogu4631][APIO2018] Circle selection 选圆圈

    Luogu 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2,...,c_n\) .我们尝试对这些圆运行这个算法: \(1\).找到这些圆中半径最大的.如果有多个半径最大的圆,选择 ...

  3. [APIO2018] Circle selection 选圆圈

    Description 给出 \(n\) 个圆 \((x_i,y_i,r_i)\) 每次重复以下步骤: 找出半径最大的圆,并删除与这个圆相交的圆 求出每一个圆是被哪个圆删除的 Solution \(k ...

  4. luogu P4631 [APIO2018] Circle selection 选圆圈

    传送门 那个当前半径最大的圆可以用堆维护.这道题一个想法就是优化找和当前圆有交的圆的过程.考虑对于所有圆心建KD-tree,然后在树上遍历的找这样的点.只要某个点子树内的点构成的矩形区域到当前圆心的最 ...

  5. 洛谷4631 [APIO2018] Circle selection 选圆圈 (KD树)

    qwq纪念AC450 一开始想这个题想复杂了. 首先,正解的做法是比较麻烦的. qwqq 那么就不如来一点暴力的东西,看到平面上点的距离的题,不难想到\(KD-Tree\) 我们用类似平面最近点对那个 ...

  6. [APIO2018]Circle selection

    https://www.zybuluo.com/ysner/note/1257597 题面 在平面上,有\(n\)个圆,记为\(c_1,c_2,...,c_n\).我们尝试对这些圆运行这个算法: 找到 ...

  7. 【APIO2018】选圆圈(平面分块 | CDQ分治 | KDT)

    Description 给定平面上的 \(n\) 个圆,用三个参数 \((x, y, R)\) 表示圆心坐标和半径. 每次选取最大的一个尚未被删除的圆删除,并同时删除所有与其相切或相交的圆. 最后输出 ...

  8. 「APIO2018选圆圈」

    「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...

  9. 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树

    题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...

随机推荐

  1. myeclipse控制台打印文字

    先来看看效果图: 下面是代码: import java.awt.Font; import java.awt.Shape; import java.awt.font.FontRenderContext; ...

  2. Xcode 编译更改 Build 输出路径

    Xcode新建一个工程,build之后,可执行文件一般在 ~/Library/Developer/Xcode/DerivedData 下. 可以把这个路径指定为当前工程目录.  指定方法 Xcode ...

  3. P4542 [ZJOI2011]营救皮卡丘

    题目链接 题意分析 我们仔细分析一下 发现题目要求用最多\(k\)条路径实现最小权覆盖 首先由于最小路径覆盖针对的是有向图 但是这是一个无向图 所以我们面向对象编程 我们维护一个数组\(d[i][j] ...

  4. 3.3 PXC Strict Mode

    摘要: 出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该 ...

  5. 架构师养成记--30.Redis环境搭建

    Redis的安装 下载地址http://redis.io/download 安装步骤: 首先需要安装gcc,把下载好的redis-3.0.0-rc2.tar.gz 放到 /usr/local 文件夹下 ...

  6. 安装vuecli和使用elememtUi

    首先需要下载node.js,这里只需要一步步的安装就可以,无需要做其他的事, 第二步:安装vue 第三步:安装脚手架 第四步: 由于国内访问npm比较慢,可以按照cnpm npm install -g ...

  7. Web服务器与浏览器的实现原理

    Web服务器与浏览器的实现原理 第一部分 为什么会出现web程序? 单机程序不能共享功能的特性导致了客户机服务器模式的诞生  有一台服务器有特定功能的程序 其他计算机通过客户端程序与服务器交流间接使用 ...

  8. Prufer序列与树的计数(坑)

    \(prufer\)序列: 无根树转\(prufer\)序列: 不断找编号最小的叶子节点,删掉并在序列中加入他相连的节点. \(prufer\)转无根树: 找到在目前\(prufer\)序列中未出现且 ...

  9. c#Task类。实现异步的一种方式

    Task和Task<TResult>是c#提供的一种实现异步功能的2个类.Task<TResult>继承Task类,有返回参数. 1.基本用法 不嵌套利用静态方法创建和运行任务 ...

  10. RealVNC

    使用Linux服务器,在一般情况下是不太用桌面环境的.不过现在我想着开发用Linux,如使用Pycharm这种IDE,还是很方便的.这样还是需要桌面环境的,然而我们位置不多,就将服务器的屏幕摘下了,那 ...