luogu P4631 [APIO2018] Circle selection 选圆圈
那个当前半径最大的圆可以用堆维护.这道题一个想法就是优化找和当前圆有交的圆的过程.考虑对于所有圆心建KD-tree,然后在树上遍历的找这样的点.只要某个点子树内的点构成的矩形区域到当前圆心的最近距离\(>2\)倍半径就不用找了
然而在loj上过不去,这时就可以用一个很鸡贼的优化,对于所有点绕原点旋转一定角度,然后就跑的过了(可能是全在一条直线上建KD-tree会出锅(雾)).稍微注意精度误差就行了
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=3e5+10;
const LL inf=1ll<<61;
const db eps=1e-3,tpd=sqrt(2)/2;
int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int nd;
struct point
{
db d[2];
int i;
bool operator < (const point &bb) const {return fabs(d[nd]-bb.d[nd])>eps?d[nd]<bb.d[nd]:i<bb.i;}
}a[N],b[N],qwq;
struct cir
{
point p;
db r;
bool operator < (const cir &bb) const {return fabs(r-bb.r)>eps?r<bb.r:p.i>bb.p.i;}
}c[N];
priority_queue<cir> hp;
int n,m,rt,ch[N][2],an[N],ii;
db mx[N][2],my[N][2];
void bui(int &o,int l,int r,int nnd)
{
if(l>r) return;
if(l==r)
{
o=b[l].i;
mx[o][0]=mx[o][1]=a[o].d[0];
my[o][0]=my[o][1]=a[o].d[1];
return;
}
int mid=(l+r)>>1;
nd=nnd;
nth_element(b+l,b+mid,b+r+1);
o=b[mid].i;
mx[o][0]=mx[o][1]=a[o].d[0];
my[o][0]=my[o][1]=a[o].d[1];
bui(ch[o][0],l,mid-1,nnd^1);
bui(ch[o][1],mid+1,r,nnd^1);
mx[o][0]=min(mx[o][0],min(mx[ch[o][0]][0],mx[ch[o][1]][0]));
mx[o][1]=max(mx[o][1],max(mx[ch[o][0]][1],mx[ch[o][1]][1]));
my[o][0]=min(my[o][0],min(my[ch[o][0]][0],my[ch[o][1]][0]));
my[o][1]=max(my[o][1],max(my[ch[o][0]][1],my[ch[o][1]][1]));
}
db dis(point aa,point bb){return (aa.d[0]-bb.d[0])*(aa.d[0]-bb.d[0])+(aa.d[1]-bb.d[1])*(aa.d[1]-bb.d[1]);}
db expt(int o)
{
if(!o) return inf;
db xx=min(mx[o][1]-qwq.d[0],qwq.d[0]-mx[o][0])<-eps?min(fabs(mx[o][1]-qwq.d[0]),fabs(qwq.d[0]-mx[o][0])):0;
db yy=min(my[o][1]-qwq.d[1],qwq.d[1]-my[o][0])<-eps?min(fabs(my[o][1]-qwq.d[1]),fabs(qwq.d[1]-my[o][0])):0;
return xx*xx+yy*yy;
}
void wk(int o)
{
if(!o||expt(o)>(db)qwq.i*(db)qwq.i+eps) return;
if(!an[o])
{
db rr=(db)qwq.i/2+c[o].r;
if(dis(a[o],qwq)<rr*rr+eps) an[o]=ii;
}
wk(ch[o][0]),wk(ch[o][1]);
}
int main()
{
n=rd();
for(int i=1;i<=n;++i)
{
db xx=rd(),yy=rd();
a[i].d[0]=tpd*xx+tpd*yy,a[i].d[1]=tpd*yy-tpd*xx;
a[i].i=i;
b[i]=a[i];
c[i].p=a[i],c[i].r=rd();
hp.push(c[i]);
}
mx[0][0]=my[0][0]=inf,mx[0][1]=my[0][1]=-inf;
bui(rt,1,n,0);
while("ji ni tai mei")
{
while(!hp.empty()&&an[hp.top().p.i]) hp.pop();
if(hp.empty()) break;
cir cc=hp.top();
hp.pop();
ii=cc.p.i;
qwq=cc.p,qwq.i=cc.r*2;
wk(rt);
}
for(int i=1;i<=n;++i) printf("%d ",an[i]);
return 0;
}
luogu P4631 [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 选圆圈(假题解)
题面 自己去\(LOJ\)上找 Sol 直接排序然后\(KDTree\)查询 然后发现\(TLE\)了 然后把点旋转一下,就过了.. # include <bits/stdc++.h> # ...
- [APIO2018] Circle selection 选圆圈
Description 给出 \(n\) 个圆 \((x_i,y_i,r_i)\) 每次重复以下步骤: 找出半径最大的圆,并删除与这个圆相交的圆 求出每一个圆是被哪个圆删除的 Solution \(k ...
- 洛谷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\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
随机推荐
- [CSP-S模拟测试]:求和(数学)
题目传送门(内部题107) 输入格式 一行五个正整数$x_1,y_1,x_2,y_2,m$ 输出格式 输出一个整数,为所求的答案对$m$取模后的结果. 样例 样例输入: 2 1 5 3 10007 样 ...
- JAVA使用easyexcel操作Excel
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本 ...
- C++入门经典-例4.7-变量的作用域
1:代码如下: // 4.7.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...
- Spring之AOP配置
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 函数-this
1.this. 解析器在调用函数的时候,每次都会向函数内部传递进一个隐含的参数(即this): this指向一个对象,这个对象称为函数执行的上下文对象.根据函数的调用方式的不同,this会指向不同的对 ...
- TensorFlow线性回归
目录 数据可视化 梯度下降 结果可视化 数据可视化 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt ...
- defineProperty和defineProperties介绍
v-model 实现的原理 angular 是 mvc 的实现原理,ng-model 是靠脏值检测实现的 脏值检测:for 循环一个个对比 vue 靠的是数据劫持 和 发布者,订阅者模式 数据劫持:O ...
- java多线程系列3:悲观锁和乐观锁
1.悲观锁和乐观锁的基本概念 悲观锁: 总是认为当前想要获取的资源存在竞争(很悲观的想法),因此获取资源后会立刻加锁,于是其他线程想要获取该资源的时候就会一直阻塞直到能够获取到锁: 在传统的关系型数据 ...
- Viola-Jones(人脸检测)
Viola-Jones 人脸检测 1.Haar特征抽取 ‘ 2. Adaboost 算法
- bat脚本延时启动exe和bat文件
@echo off ping >nul start D:\exe\a.exe start "C:\Program Files\维护工具\卸载清除一键清理系统垃圾文件.bat" ...