CF1446F-Line Distance【计算几何,树状数组,二分】
正题
题目链接: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【计算几何,树状数组,二分】的更多相关文章
- POJ 2182 Lost Cows 【树状数组+二分】
题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- POJ 2828 Buy Tickets (线段树 or 树状数组+二分)
题目链接:http://poj.org/problem?id=2828 题意就是给你n个人,然后每个人按顺序插队,问你最终的顺序是怎么样的. 反过来做就很容易了,从最后一个人开始推,最后一个人位置很容 ...
- TZOJ 4602 高桥和低桥(二分或树状数组+二分)
描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算“淹了两次”.举 ...
- 树状数组+二分||线段树 HDOJ 5493 Queue
题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...
- P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
- The Stream of Corning 2( 权值线段树/(树状数组+二分) )
题意: 有两种操作:1.在[l,r]上插入一条值为val的线段 2.问p位置上值第k小的线段的值(是否存在) 特别的,询问的时候l和p合起来是一个递增序列 1<=l,r<=1e9:1< ...
- 牛客多校第3场 J 思维+树状数组+二分
牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...
- ZOJ 3157 Weapon --计算几何+树状数组
题意:给一些直线,问这些直线在直线x=L,x=R之间有多少个交点. 讲解见此文:http://blog.sina.com.cn/s/blog_778e7c6e0100q64a.html 首先将直线分别 ...
- 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 ...
随机推荐
- open62541(opcua)传输延迟探索小记
缘起 将open62541作为中间件使用代替自定义数据的RPC,client通过订阅valueChange来接收数据.使用时发现有一些问题: 前后两次产生的数据相同时,不会触发valueChange ...
- 【转】Mysql中事务ACID实现原理
转自:https://www.cnblogs.com/rjzheng/p/10841031.html 作者:孤独烟 引言 照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" ...
- clojure配置
1.转换clojure工程为eclipse工程 Install Counterclockwise plugin in Eclipse (from eclipse marketplace). This ...
- hdfs数据迁移
有时候可能会进行hadoop集群数据拷贝的情况,可用以下命令进行拷贝 需要在目标集群上来进行操作 hadoop distcp hdfs://192.168.1.233:8020/user/hive/w ...
- 刷题-力扣-63. 不同路径 II
63. 不同路径 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii/ 著作权归领扣网络所有.商业转 ...
- VS在调试桌面程序时,cout到控制台方法
参考博客:https://blog.csdn.net/xinxinsky/article/details/80733400 C++桌面程序设置 Properties -> Build Event ...
- 编写你的第一个Django应用
安装 Python 作为一个 Python Web 框架,Django 需要 Python.更多细节请参见 我应该使用哪个版本的 Python 来配合 Django?. Python 包含了一个名为 ...
- MySQL-存储引擎-1
一.MySQL存储引擎 mysql> create table country( -> country_id smallint unsigned not null auto_increme ...
- ❤️用武侠小说的形式来阅读LinkedList的源码,绝了!
一.LinkedList 的剖白 大家好,我是 LinkedList,和 ArrayList 是同门师兄弟,但我俩练的内功却完全不同.师兄练的是动态数组,我练的是链表. 问大家一个问题,知道我为什么要 ...
- linux 查看用户密码
2021-07-26 1.查看前三个密码 head -3 / etc / passwd # 注解 /etc/passwd 中一行记录对应着一个用户,每行记录又被冒号 (:) 分隔为 7 个字段,其格式 ...