BZOJ5465 APIO2018选圆圈(KD-Tree+堆)
考虑乱搞,用矩形框圆放KD-Tree上,如果当前删除的圆和矩形有交就递归下去删。为防止被卡,将坐标系旋转一定角度即可。注意eps稍微设大一点,最好开上long double。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define ll long long
#define N 300010
#define double long double
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
const double PI=acos(-1.0);
const double eps=1E-;
int n,c,cnt,root,ans[N];
struct circle
{
double d[];int r,i;
bool operator <(const circle&a) const
{
return d[c]<a.d[c];
}
void rotate(double alpha)
{
double u=d[]*cos(alpha)-d[]*sin(alpha);
double v=d[]*sin(alpha)+d[]*cos(alpha);
d[]=u,d[]=v;
}
}a[N];
struct KDTree{int ch[];double a[][];circle p;
}tree[N];
double sqr(double x){return x*x;}
bool iscross(circle x,circle y){return sqr(x.d[]-y.d[])+sqr(x.d[]-y.d[])<sqr(x.r+y.r)+eps;}
double max(double x,double y,double z){return max(max(x,y),z);}
double iscross(circle p,double a[][]){return sqr(max(p.d[]-a[][],a[][]-p.d[],(double)))+sqr(max(p.d[]-a[][],a[][]-p.d[],(double)))<sqr(p.r)+eps;}
void build(int &k,int l,int r,int op)
{
if (l>r) return;
k=++cnt,c=op;int mid=l+r>>;nth_element(a+l,a+mid,a+r+);
tree[k].p=a[mid];
tree[k].a[][]=a[mid].d[]-a[mid].r,tree[k].a[][]=a[mid].d[]+a[mid].r,
tree[k].a[][]=a[mid].d[]-a[mid].r,tree[k].a[][]=a[mid].d[]+a[mid].r;
for (int i=l;i<=r;i++)
tree[k].a[][]=min(tree[k].a[][],a[i].d[]-a[i].r),tree[k].a[][]=max(tree[k].a[][],a[i].d[]+a[i].r),
tree[k].a[][]=min(tree[k].a[][],a[i].d[]-a[i].r),tree[k].a[][]=max(tree[k].a[][],a[i].d[]+a[i].r);
build(tree[k].ch[],l,mid-,op^);
build(tree[k].ch[],mid+,r,op^);
}
void find(int k,circle x)
{
if (!ans[tree[k].p.i]&&iscross(tree[k].p,x)) ans[tree[k].p.i]=x.i;
if (tree[k].ch[]&&iscross(x,tree[tree[k].ch[]].a)) find(tree[k].ch[],x);
if (tree[k].ch[]&&iscross(x,tree[tree[k].ch[]].a)) find(tree[k].ch[],x);
}
struct cmp
{
bool operator ()(const circle&a,const circle&b) const
{
return a.r<b.r||a.r==b.r&&a.i>b.i;
}
};
priority_queue<circle,vector<circle>,cmp> q;
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5465.in","r",stdin);
freopen("bzoj5465.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++)
{
a[i].d[]=read(),a[i].d[]=read(),a[i].i=i,a[i].r=read();
a[i].rotate(PI/);
q.push(a[i]);
}
build(root,,n,);
while ()
{
while (!q.empty()&&ans[q.top().i]) q.pop();
if (q.empty()) break;
circle x=q.top();q.pop();ans[x.i]=x.i;
find(root,x);
}
for (int i=;i<=n;i++) printf("%d ",ans[i]);
return ;
}
BZOJ5465 APIO2018选圆圈(KD-Tree+堆)的更多相关文章
- BZOJ5465: [APIO 2018] 选圆圈(K-D Tree)
题意 题目链接 Sol 下面是错误做法,正解请看这里 考虑直接用K-D tree模拟.. 刚开始想的是维护矩形最大最小值,以及子树中最大圆的位置,然后... 实际上最大圆的位置是不用维护的,直接把原序 ...
- [BZOJ5465][APIO2018]选圆圈(KD-Tree)
题意:给你n个圆,每次选择半径最大的,将它和与它相交的圆全部删去,输出每个圆是在哪次被删的. KD树模板题.用一个矩形框住这个圆,就可以直接剪枝了.为了防止被卡可以将点旋转一个角度,为了保险还可以多转 ...
- 「APIO2018选圆圈」
「APIO2018选圆圈」 题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1, c_2, \ldots, c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径 ...
- LOJ 2586 「APIO2018」选圆圈——KD树
题目:https://loj.ac/problem/2586 只会 19 分的暴力. y 都相等,仍然按直径从大到小做.如果当前圆没有被删除,那么用线段树把 [ x-r , x+r ] 都打上它的标记 ...
- LOJ2586 APIO2018 选圆圈
考前挣扎 KD树好题! 暴力模拟 通过kd树的结构把子树内的圈圈框起来 然后排个序根据圆心距 <= R1+R2来判断是否有交点 然后随便转个角度就可以保持优越的nlgn啦 卡精度差评 必须写ep ...
- 【LG4631】[APIO2018]Circle selection 选圆圈
[LG4631][APIO2018]Circle selection 选圆圈 题面 洛谷 题解 用\(kdt\)乱搞剪枝. 维护每个圆在\(x.y\)轴的坐标范围 相当于维护一个矩形的坐标范围为\([ ...
- 【APIO2018】选圆圈(平面分块 | CDQ分治 | KDT)
Description 给定平面上的 \(n\) 个圆,用三个参数 \((x, y, R)\) 表示圆心坐标和半径. 每次选取最大的一个尚未被删除的圆删除,并同时删除所有与其相切或相交的圆. 最后输出 ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
- 「APIO2018」选圆圈
传送门 Description 有\(n\)个圆,每次找到这些圆中半径最大中的编号最小的圆,删除ta及与其有交集的所有圆. 对于每个圆,求出它是被哪一个圆删除的. Solution K-D Tree ...
随机推荐
- Mac 如何显示隐藏文件夹并设置快捷键
通过在终端运行命令可以控制隐藏文件是否显示: 输入defaults write com.apple.finder AppleShowAllFiles NO 就不显示, 输入defaults write ...
- RESTful API设计概要
一.简介 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fiel ...
- 12、JAVA内存模型与线程
一.JMM 有序性,可见性,原子性 synchorize :3个性都有: volatile:保证可见性+禁止指令重排: 二.线程的五种状态 面向过程与面向对象的差别 面向过程:站在计算机的角度分析和解 ...
- HW 2017 12 17可禾大佬神题
好不容易搞来的题目,不写一写怎么行呢. 不过难度真心不高(一小时K掉),都是老题+暴力题,没有欧洲玄学. 再说一句,这试卷是叶可禾出的吧. T1 好老的题目,看到有多组数据我还怕了,以为有更流弊的算法 ...
- MiZ702学习笔记8——让MiZ702变身PC的方法
首先你需要一个安装好的linux系统,这里我用的是Ubuntu的虚拟机.VMWare的话,选择较高版本的成功率会高些(当然根据自己电脑的配置进行选择). 打开Ubuntu的虚拟机,找到一个叫做Disk ...
- 升级webpack2
更新:webpack3已经出来了,官方说从2到升级到3不用改一行配置,98%的人没有错误. 项目中用的是webpack1.webpack2已经出来一段时间了.决定升级.其实改动不是很大.修改加测试共花 ...
- Google是如何教会机器玩Atari游戏的
转自:http://blog.csdn.net/revolver/article/details/50177219 今年上半年(2015年2月),Google在Nature上发表了一篇论文:Human ...
- idea ssm项目迁移到另一台机器上时出现不能正常启动项目的解决方案
首先右下角提示关联spring文件,关联之,然后启动,发现项目无法启动,然后开始排错 首先从这个日志里发现了这么一条提示信息 然后百度了一下,答案都是说 web.xml 之类的 spring拦截器问题 ...
- TensorFlow 训练MNIST数据集(2)—— 多层神经网络
在我的上一篇随笔中,采用了单层神经网络来对MNIST进行训练,在测试集中只有约90%的正确率.这次换一种神经网络(多层神经网络)来进行训练和测试. 1.获取MNIST数据 MNIST数据集只要一行代码 ...
- 物理机通过http访问eNSP虚拟Server
由于测试需要,本文主要通过一个简单的例子介绍通过物理机的浏览器访问华为eNSP虚拟Server,访问网页. 1.首先配置虚拟网卡的地址 2.通过华为的eNSP模拟软件,做出如下拓扑结构图,配置地址如图 ...