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 ...
随机推荐
- SVN 错误收集
一.the working copy is locked due to a previous error 解决办法:在 Cornerstone 右键本地工程 --> clean.
- SystemView SEGGER FreeRTOS 移植和使用
/* 官方帮助英文翻译文档参考:https://blog.csdn.net/bjr2016/article/category/7275877. */ /* 移植文档参考:https://blog.cs ...
- Linux常用系统信息查看命令
[转]http://yulans.cn/linux/linux%E5%B8%B8%E7%94%A8%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF%E6%9F%A5%E7%9C ...
- JS设置cookie、读取cookie、删除cookie(转载)
JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的.而cookie是运行在客户端的,所以可以用JS来设置cookie.假设有这样一种情 ...
- 使用参数化查询防止SQL注入漏洞(转)
SQL注入的原理 以往在Web应用程序访问数据库时一般是采取拼接字符串的形式,比如登录的时候就是根据用户名和密码去查询: string sql * FROM [User] WHERE UserName ...
- # 2017-2018-2 20155319《网络对抗技术》Exp9 :Web安全基础
2017-2018-2 20155319<网络对抗技术>Exp9 :Web安全基础 实践过程 webgoat准备 从GitHub上下载jar包(老师的虚拟机中有 无需下载) 拷贝到本地,并 ...
- idea git pull项目到本地时容易出现的问题
有时候pull到本地,出了各种错误,其实是因为搞来搞去的,容易出问题,所以最好的方法是拿原有打包好的整个稳定能跑的项目环境, 先git add,然后vcs重置head为hard,然后再pull,一般就 ...
- centos 7 搭建开源堡垒机 Teleport 遇到的问题解决
不得不说 centos7 的环境版本就是高,没有再出现6.5下那些依赖组件的版本支持过低的错误了,所以说现在个人用户还是推荐用7,企业生产环境的话,可能6.5适合一些,至少2年前是这样. 安装过程: ...
- effective c++ 笔记 (26-29)
//---------------------------15/04/09---------------------------- //#26 尽可能延后变量定义式的出现时间 { /* 1:只要 ...
- 【转载】python %s %d %f
%s 字符串 string="hello" #%s打印时结果是hello print "string=%s" % string # output: s ...