CF1446F

Posted chasedeath

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1446F相关的知识,希望对你有一定的参考价值。

CF1446F - Line Distance

题目大意

给定\\(n\\)个点\\(P_i\\),在每个点对之间连一条线\\(P_iP_j\\)

求所有线到原点距离的第\\(k\\)


分析

这个\\(k\\)大问题的\\(k\\)\\(O(n^2)\\)级的,因此不是调整,可以考虑二分答案\\(L\\)

考虑如何确定\\(d(O,P_iP_j)>L\\),容易发现这等价于

\\(P_iP_j\\)与圆\\(C:x^2+y^2=L^2\\)无交

假设当前确定了\\(P_i\\),考虑什么时候\\(P_j\\)是合法的

img1

灰色线是切线,用蓝色区域标出了\\(d(O,P_iP_j)>L\\)的范围

直接统计蓝色区域的点并不容易,考虑对于这些点也作切线

Snipaste_2021-05-23_11-40-50.png

容易发现这些点的两个切点恰好被\\(P_i\\)的两个切点分隔开

通过求切点角度,转化为二维区间问题,用树状数组解决

复杂度为\\(O(n\\log n\\log x)\\),其中\\(x\\)为精度范围

const int N=2e5+10,INF=1e9+10;
const db eps=1e-7,PI=acos((db)-1);

int n; ll m;
int X[N],Y[N];
struct Node{
	db x,y;
	bool operator < (const Node __) const {
		return x<__.x;
	}
} A[N];
db H[N];
int C,HC;

struct BIT{
	int s[N],n;
	void Init(int m){ n=m,memset(s,0,(n+1)<<2); }
	void Add(int p,int x){
		while(p<=n) s[p]+=x,p+=p&-p;
	}
	int Que(int p){
		int res=0;
		while(p) res+=s[p],p-=p&-p;
		return res;
	}
} T;

db norm(db x){
	if(x<0) x+=2*PI;
	if(x>=2*PI) x-=2*PI;
	return x;
}
ll Calc(db L) {
	C=HC=0;
	rep(i,1,n) {
		db D=sqrt(X[i]*X[i]+Y[i]*Y[i]);
		if(L>=D) continue;
		db x=atan2(Y[i],X[i]),y=acos(L/D);
		db l=norm(x-y),r=norm(x+y);
		if(l>r) swap(l,r);
		A[++C]=(Node){l,r};
		H[++HC]=l,H[++HC]=r;
	}
	sort(H+1,H+HC+1);
	ll ans=1ll*n*(n-1)/2;
	sort(A+1,A+C+1),T.Init(HC);
	rep(i,1,C) {
		A[i].x=lower_bound(H+1,H+HC+1,A[i].x)-H;
		A[i].y=lower_bound(H+1,H+HC+1,A[i].y)-H;
		ans-=T.Que(A[i].y)-T.Que(A[i].x);
		T.Add(A[i].y,1);
	}
	return ans;
}

int main(){
	n=rd(),m=rd<ll>();
	rep(i,1,n) X[i]=rd(),Y[i]=rd();
	db l=eps,r=2e4;
	while(r>l*(1+eps)) {
		db mid=(l+r)/2;
		if(Calc(mid)<m) l=mid;
		else r=mid;
	}
	printf("%.10lf\\n",l);
}

以上是关于CF1446F的主要内容,如果未能解决你的问题,请参考以下文章

cf 模拟

CF1435 游记

无法解析符号 c882c94be45fff9d16a1cf845fc16ec5

本人想学习破解技术但是看不懂反汇编代码!求助!!

微信小程序代码片段

VSCode自定义代码片段——CSS选择器