[APIO2018] Circle selection 选圆圈(假题解)
题面
自己去\(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 选圆圈(假题解)的更多相关文章
- 【LG4631】[APIO2018]Circle selection 选圆圈
[LG4631][APIO2018]Circle selection 选圆圈 题面 洛谷 题解 用\(kdt\)乱搞剪枝. 维护每个圆在\(x.y\)轴的坐标范围 相当于维护一个矩形的坐标范围为\([ ...
- [Luogu4631][APIO2018] Circle selection 选圆圈
Luogu 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2,...,c_n\) .我们尝试对这些圆运行这个算法: \(1\).找到这些圆中半径最大的.如果有多个半径最大的圆,选择 ...
- [APIO2018] Circle selection 选圆圈
Description 给出 \(n\) 个圆 \((x_i,y_i,r_i)\) 每次重复以下步骤: 找出半径最大的圆,并删除与这个圆相交的圆 求出每一个圆是被哪个圆删除的 Solution \(k ...
- luogu P4631 [APIO2018] Circle selection 选圆圈
传送门 那个当前半径最大的圆可以用堆维护.这道题一个想法就是优化找和当前圆有交的圆的过程.考虑对于所有圆心建KD-tree,然后在树上遍历的找这样的点.只要某个点子树内的点构成的矩形区域到当前圆心的最 ...
- 洛谷4631 [APIO2018] Circle selection 选圆圈 (KD树)
qwq纪念AC450 一开始想这个题想复杂了. 首先,正解的做法是比较麻烦的. qwqq 那么就不如来一点暴力的东西,看到平面上点的距离的题,不难想到\(KD-Tree\) 我们用类似平面最近点对那个 ...
- [APIO2018]Circle selection
https://www.zybuluo.com/ysner/note/1257597 题面 在平面上,有\(n\)个圆,记为\(c_1,c_2,...,c_n\).我们尝试对这些圆运行这个算法: 找到 ...
- 【APIO2018】选圆圈(平面分块 | CDQ分治 | KDT)
Description 给定平面上的 \(n\) 个圆,用三个参数 \((x, y, R)\) 表示圆心坐标和半径. 每次选取最大的一个尚未被删除的圆删除,并同时删除所有与其相切或相交的圆. 最后输出 ...
- 「APIO2018选圆圈」
「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
随机推荐
- php prepare
详见 https://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql- ...
- 校验 CentOS 7 镜像文件
验证镜像文件的原因 CentOS Vault(http://vault.centos.org/)页脚的镜像站链接上有段英文,指出页脚的镜像站链接不受 CentOS 团队的监控,除此之外还有一个原因就是 ...
- 网络基础 08_NAT
1 NAT的基本概念 为什么需要NAT IPv4地址紧缺 什么是NAT NAT(Network Address Translation) 私有IPv4地址 10.0.0.0 - 10.255.255. ...
- 后台开发面试题(.net与java)
最近面试了几家公司,发现大部分公司面试题有相似的地方.现在此记录下我还记得的一些题: JAVA部分: 1.Java Map 按Key排序和按Value排序: 参考链接:Java Map 按Key排序和 ...
- UI1
计算机工程系 目 录 实验一 Photoshop基本界面熟悉 3 实验二 PhotoShop常用工具的使用 4 实验三 图象和图层的处理 7 实验四 各种滤镜方式的处理 13 实验五 Ph ...
- Go语言目录
为什么学习Go语言 第一章 环境搭建 Windows搭建Go语言环境 第二章 Go语言基础 Go语言介绍 Go语言命名 Go语言内置类型和函数 Go语言特殊函数介绍 Go语言运算符 第三章 Go语言程 ...
- windows server 2012 valid key
好吧,网页三剑客. 1, load disc iso 2,check ip settings, 3,net-inst-server-start 4,power Node, F2 4.1 F7 usbc ...
- Monkey and Banana
Monkey and BananaTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Window对象的判定方法
/* window对象的判定,由于ECMA是不规范Host对象,window对象属于Host,所以也没有约定,所以就算是Object.prototype也对它无可奈何, 而且如果根据window.wi ...
- Window.localStorage
博客园 https://www.cnblogs.com/st-leslie/p/5617130.html 参考文档 https://developer.mozilla.org/zh-CN/docs/W ...