正题

题目链接:https://www.luogu.com.cn/problem/CF1446F


题目大意

给出\(n\)个点,求所有点对构成的直线中与原点距离第\(k\)小的距离

\(2\leq n\leq 10^5,1\leq k\leq \frac{n(n-1)}{2}\)


解题思路

二分还是挺显然的,考虑二分了之后怎么判断一个距离以内的直线数量

两个点对之间的直线在原点距离\(d\)以内,也就是这条直线经过原点为中心半径为\(d\)的圆。换一种理解,也就是如果有这个圆那么这两个点对之间无法相互看见。

现在问题变为了求有多少个点对之间无法相互看见,给张官方题解的图片就挺容易理解的



也就是说我们对于每个点找到它与圆的两个切点之间在圆上构成的一个区间。

如果两个点的区间有交集那么他们就可以相互看见。

现在问题就变为了求有多少对区间有交。

这个直接用树状数组统计就好了。

环的话直接断开,跨越了环的就取反。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define lowbit(x) (x&-x)
using namespace std;
const ll N=2e5+10;
double eps=1e-8,Pi=acos(-1);
ll n,k,cnt,m,t[N],p[N],l[N],r[N];
double a[N],b[N],c[N],L[N],R[N];
bool v[N];
void Change(ll x,ll val){
while(x<=cnt){
t[x]+=val;
x+=lowbit(x);
}
return;
}
ll Ask(ll x){
ll ans=0;
while(x){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
bool cmp(ll x,ll y)
{return l[x]<l[y];}
ll check(double d){
cnt=0;m=0;
for(ll i=1;i<=n;i++)v[i]=0;
for(ll i=1;i<=n;i++){
double dis=sqrt(a[i]*a[i]+b[i]*b[i]);
if(dis-d<eps){v[i]=1;continue;}
double ang=atan2(b[i],a[i]),ta=acos(d/dis);
L[i]=ang-ta;R[i]=ang+ta;
if(L[i]<-Pi)L[i]+=2*Pi;
if(R[i]>Pi)R[i]-=2*Pi;
if(L[i]>R[i])swap(L[i],R[i]);
c[++cnt]=L[i];c[++cnt]=R[i];
}
sort(c+1,c+1+cnt);
for(ll i=1;i<=n;i++){
if(v[i])continue;p[++m]=i;
l[i]=lower_bound(c+1,c+1+cnt,L[i])-c;
r[i]=lower_bound(c+1,c+1+cnt,R[i])-c;
}
memset(t,0,sizeof(t));
sort(p+1,p+1+m,cmp);
ll ans=n*(n-1)/2;
for(ll i=1;i<=m;i++){
ll x=p[i];
ans-=Ask(r[x])-Ask(l[x]-1);
Change(r[x],1);
}
return ans;
}
signed main()
{
scanf("%lld%lld",&n,&k);
for(ll i=1;i<=n;i++)
scanf("%lf%lf",&a[i],&b[i]);
double l=0,r=20000;
while(r-l>=eps){
double mid=(l+r)/2.0;
if(check(mid)<k)l=mid;
else r=mid;
}
printf("%.10lf",l);
return 0;
}

CF1446F-Line Distance【计算几何,树状数组,二分】的更多相关文章

  1. POJ 2182 Lost Cows 【树状数组+二分】

    题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  2. POJ 2828 Buy Tickets (线段树 or 树状数组+二分)

    题目链接:http://poj.org/problem?id=2828 题意就是给你n个人,然后每个人按顺序插队,问你最终的顺序是怎么样的. 反过来做就很容易了,从最后一个人开始推,最后一个人位置很容 ...

  3. TZOJ 4602 高桥和低桥(二分或树状数组+二分)

    描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算“淹了两次”.举 ...

  4. 树状数组+二分||线段树 HDOJ 5493 Queue

    题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...

  5. P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

  6. The Stream of Corning 2( 权值线段树/(树状数组+二分) )

    题意: 有两种操作:1.在[l,r]上插入一条值为val的线段 2.问p位置上值第k小的线段的值(是否存在) 特别的,询问的时候l和p合起来是一个递增序列 1<=l,r<=1e9:1< ...

  7. 牛客多校第3场 J 思维+树状数组+二分

    牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...

  8. ZOJ 3157 Weapon --计算几何+树状数组

    题意:给一些直线,问这些直线在直线x=L,x=R之间有多少个交点. 讲解见此文:http://blog.sina.com.cn/s/blog_778e7c6e0100q64a.html 首先将直线分别 ...

  9. HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

随机推荐

  1. leaflet antvPath示例

    参考:https://www.cnblogs.com/vichang/p/9438870.html leaflet-antvPath官网:https://github.com/rubenspgcava ...

  2. 十七:使用JDBC处理MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...

  3. WPF---数据绑定之RelativeSource(五)

    一.概述 当Binding有明确的数据来源的时候,我们可以用Source或者ElementName赋值的办法让Binding与之关联. 但是,有时候当我们不能确定作为Source的对象叫什么名字的时候 ...

  4. C++泛型编程之类模板

    泛型语义 泛型(Generic Programming),即是指具有在多种数据类型上皆可操作的含意.泛型编程的代表作品 STL 是一种高效.泛型.可交互操作的软件组件. 泛型编程最初诞生于 C++中, ...

  5. linux的一般命令------附加

    1.cat /etc/redhat-release             查看linux版本 2. ps -ef|grep ssh                        查看进程在不在 3. ...

  6. linux(2)-----新装linux配置

    1.配置本机ip,刚装的Linux无内网ip vi /etc/susconfig/network-scripts/ifcfq-ens33    编辑配置文件 最后一行改为yes service net ...

  7. linux 常用命令(五)——(centos7-centos6.8)JDK安装

    1.安装jdk前先检测系统是否带有OpenJDK:若存在则删除 查看: java -version 查询出OpenJDK相关的文件:rpm -qa | grep java 删除OpenJDK相关的文件 ...

  8. C++类和对象笔记

    笔记参考C++视频课程 黑马C++ C++ 面向对象的三大特性:封装.继承.多态 目录 目录 目录 一.封装 1.1 封装的意义-属性和行为 1.2 struct和class的区别 1.3 成员属性设 ...

  9. CSP 2021 游记

    \(\text{Day -INF}\) 看见了 \(\text{SCP2021}\) 的报名通知,想着应该教练会让我们统一报名,就没放在心上 然后-- 然后过了二十多天教练根本没有提报名的事情,搞得我 ...

  10. Activiti 学习(二)—— Activiti 流程定义和部署

    概述 在这一节,我们将创建一个 Activit 工作流,并启动这个流程,主要包含以下几个步骤: 定义流程,按照 BPMN 的规范,使用流程定义工具,用流程符号把整个流程描述出来 部署流程,把画好的流程 ...