考前挣扎

KD树好题!

暴力模拟 通过kd树的结构把子树内的圈圈框起来

然后排个序根据圆心距 <= R1+R2来判断是否有交点

然后随便转个角度就可以保持优越的nlgn啦

卡精度差评 必须写eps差评

//Love and Freedom.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db long double
#define inf 20021225
#define ll long long
#define mxn 310000
#define eps 1e-3
using namespace std; struct poi
{
db x,y;
poi(){}
poi(db _x,db _y){x=_x,y=_y;}
}; struct circle
{
db r; poi pos; int id;
circle(){}
circle(poi _pos,db _r){pos=_pos;r = _r;}
}cc[mxn];
int ans[mxn];
struct node
{
int son[2],id; //poi p;
db r,mr,mx[2],mn[2],pos[2];
};
bool flag;
bool cmp(circle a,circle b)
{
if(flag?abs(a.pos.x - b.pos.x)<eps:abs(a.pos.y-b.pos.y)<eps) return a.r>b.r;
return flag?a.pos.x<b.pos.x:a.pos.y<b.pos.y;
} db dis(poi a,poi b)
{
return (a.x-b.x) * (a.x-b.x) + (a.y-b.y) * (a.y-b.y);
}
struct KD
{
node t[mxn]; int rt;
void update(int x)
{
int l = t[x].son[0];
int r = t[x].son[1];
for(int c = 0;c < 2; c++)
{
if(l) t[x].mx[c]=max(t[l].mx[c],t[x].mx[c]),t[x].mn[c]=min(t[l].mn[c],t[x].mn[c]);
if(r) t[x].mx[c]=max(t[r].mx[c],t[x].mx[c]),t[x].mn[c]=min(t[r].mn[c],t[x].mn[c]);
}
if(l) t[x].mr=max(t[x].mr,t[l].mr);
if(r) t[x].mr=max(t[x].mr,t[r].mr);
}
void build(int &x,int l,int r,bool w)
{
flag = w; sort(cc+l,cc+r+1,cmp);
int mid = l+r>>1; x = mid;
t[x].mr = t[x].r = cc[mid].r; t[x].id = cc[mid].id;
for(int c = 0;c < 2;c++)
t[x].pos[c] = t[x].mn[c] = t[x].mx[c] = c?cc[mid].pos.y:cc[mid].pos.x;
if(l<mid) build(t[x].son[0],l,mid-1,w^1);
if(mid<r) build(t[x].son[1],mid+1,r,w^1);
update(x);
}
bool del(circle goal, circle tmp)
{
if(dis(goal.pos,tmp.pos) - (goal.r+tmp.r)*(goal.r+tmp.r)<=eps) return true;
return false;
}
db check(int x,circle goal)
{
db ans = 0;
for(int c = 0;c < 2;c++)
{
db wz = (c?goal.pos.y:goal.pos.x),tmp;
if(wz>=t[x].mn[c] && wz<=t[x].mx[c]) tmp = 0;
else tmp = min(abs(t[x].mn[c]-wz),abs(t[x].mx[c]-wz));
ans += tmp*tmp;
}
return ans;
}
void query(int x,circle goal,int w)
{
if(!ans[t[x].id] && del(goal,circle(poi(t[x].pos[0],t[x].pos[1]),t[x].r))) ans[t[x].id] = w;
int l = t[x].son[0], r = t[x].son[1]; db d1,d2;
if(l)
{
d1 = check(l,goal);
if((t[l].mr+goal.r)*(t[l].mr+goal.r) -d1>= -eps) query(l,goal,w);
}
if(r)
{
d2 = check(r,goal);
if((t[r].mr+goal.r)*(t[r].mr+goal.r) -d2>= -eps) query(r,goal,w);
}
}
}kd;
bool qaq(circle a,circle b)
{
return abs(a.r-b.r)<eps?a.id<b.id:a.r>b.r;
} const db phi = 1.05426;
poi rotate(poi a)
{
return poi(cosl(phi)*a.x-sinl(phi)*a.y,sinl(phi)*a.x+cosl(phi)*a.y);
} int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%Lf%Lf%Lf",&cc[i].pos.x,&cc[i].pos.y,&cc[i].r),cc[i].id=i;
cc[i].pos = rotate(cc[i].pos);
}
kd.build(kd.rt,1,n,0);
sort(cc+1,cc+n+1,qaq);
for(int i=1;i<=n;i++)
if(!ans[cc[i].id])
kd.query(kd.rt,cc[i],cc[i].id);
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}

LOJ2586 APIO2018 选圆圈的更多相关文章

  1. 「APIO2018选圆圈」

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

  2. BZOJ5465 APIO2018选圆圈(KD-Tree+堆)

    考虑乱搞,用矩形框圆放KD-Tree上,如果当前删除的圆和矩形有交就递归下去删.为防止被卡,将坐标系旋转一定角度即可.注意eps稍微设大一点,最好开上long double. #include< ...

  3. [BZOJ5465][APIO2018]选圆圈(KD-Tree)

    题意:给你n个圆,每次选择半径最大的,将它和与它相交的圆全部删去,输出每个圆是在哪次被删的. KD树模板题.用一个矩形框住这个圆,就可以直接剪枝了.为了防止被卡可以将点旋转一个角度,为了保险还可以多转 ...

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

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

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

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

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

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

  7. 【loj2586】【APIO2018】选圆圈

    题目 有 \(n\) 个圆$c_1,c_2, \cdots , c_n $,执行如下的操作: 找到剩下的半径最大的圆删除并删除所有和它有交的其他并没有被删除的圆: 求每个圆是被那个圆删除的: $1 \ ...

  8. [loj2586]选圆圈

    下面先给出比较简单的KD树的做法-- 根据圆心建一棵KD树,然后模拟题目的过程,考虑搜索一个圆 剪枝:如果当前圆[与包含该子树内所有圆的最小矩形]都不相交就退出 然而这样的理论复杂度是$o(n^2)$ ...

  9. LOJ 2586 「APIO2018」选圆圈——KD树

    题目:https://loj.ac/problem/2586 只会 19 分的暴力. y 都相等,仍然按直径从大到小做.如果当前圆没有被删除,那么用线段树把 [ x-r , x+r ] 都打上它的标记 ...

随机推荐

  1. Delphi 清理程序内存

    procedure ClearMemory;begin        if Win32Platform = VER_PLATFORM_WIN32_NT then        begin        ...

  2. 当执行一条查询语句时,MySQL内部经历了什么?

    假如说我们有一张表 T ,表里只有一个字段 ID,当我们执行下边这条SQL语句时: mysql> select * fron T where ID=10; 在我们眼中能看到的只是输入一条 SQL ...

  3. spring管理的事务

    之前对spring的事务传播机制没有概念,花点时间去看了事务的源码,以及这些事务传播机制使用的文档,在此做一下简单的笔记 正文 下面说提到的共享事务的意思就是几个service共用同一个事务,如传播机 ...

  4. Python网络爬虫-爬取微博热搜

    微博热搜的爬取较为简单,我只是用了lxml和requests两个库 url=https://s.weibo.com/top/summary?Refer=top_hot&topnav=1& ...

  5. 刚性方程 Stiff equation

    In mathematics, a stiff equation is a differential equation for which certain numerical methods for ...

  6. Delphi Canvas的FillRect(const Rect: TRect) 函数的作用

    http://blog.163.com/zhangzhifeng688@126/blog/static/165262758201131211341460/ Delphi Canvas的FillRect ...

  7. 大数据学习笔记之Zookeeper(三):Zookeeper理论篇(二)

    文章目录 3.1 数据结构 3.2 节点类型 3.3 特点 3.4 选举机制 3.5 stat结构体 3.6 监听器原理 3.1 数据结构 ZooKeeper数据模型的结构与Unix文件系统很类似,整 ...

  8. 下载工具 qBittorrent 使用

    官网地址,软件可以在官网上下载. GitHub 源码 知乎的参考链接 qBittorrent 是开源软件,支持用 BT 种子或种子的链接下载,也可以用磁力链接进行下载. 搜索功能 qBittorren ...

  9. Unity3D架构之PureMVC

    之前了解过UI实现框架大多是用MVC架构的,才听说有这么一个基于MVC的跨平台开源框架叫PureMVC,前几天用到了做了一下,写一写分析总结官网位置:http://puremvc.org/ PureM ...

  10. User-Based Collaborative Recommender System

    Collaborative Recommender System基于User给Item的打分表,认为相似度很高的用户,会对同一个item给出相似的分数,找出K个相似度最高的用户,集合他们的打分,来推算 ...