zoukankan      html  css  js  c++  java
  • CF1446F Line Distance

    若干个点,两两间连线。问和原点距离第(k)大的直线,到原点距离是多少。

    (nle 10^5)


    显然二分,然后就是计数。

    结论:两个点(A,B)分别引切线到圆,分别记切点为(A_0,A_1,B_0,B_1)。如果(A_0A_1,B_0B_1)相交,那么(AB)与圆相离。

    画画图即可证明。

    离散化之后树状数组即可。注意判断一下点在圆内的情况。


    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cassert>
    #define N 100005
    #define ll long long
    const double PI=acos(-1);
    int n;
    ll k;
    struct DOT{double x,y;} d[N];
    double sqr(double x){return x*x;}
    void adjust(double &t){
    	t-=int(t/(2*PI))*(2*PI);
    	if (t<-1e-10) t+=2*PI;
    }
    int m;
    DOT q[N];
    int nv;
    double *p[N*2];
    bool cmpp(double *x,double *y){return *x<*y;}
    int t[N*2];
    void add(int x){
    	for (;x<=nv;x+=x&-x)
    		t[x]++;
    }
    int query(int x){
    	int r=0;
    	for (;x;x-=x&-x)
    		r+=t[x];
    	return r;
    }
    void init(int n){
    	sort(p+1,p+n+1,cmpp);
    	nv=0;
    	double last=19260817;
    	for (int i=1;i<=n;++i){
    		if (*p[i]!=last)
    			last=*p[i],++nv;
    		*p[i]=nv;
    	}
    	memset(t,0,sizeof(int)*(nv+1));
    }
    bool cmpq(DOT a,DOT b){return a.y<b.y;}
    void insert(double l,double r){
    	adjust(l);
    	adjust(r);
    	if (l>r) swap(l,r);
    	q[++m]={l,r};
    }
    ll res;
    ll calc(double r){
    	m=0;
    	for (int i=1;i<=n;++i){
    		double l=sqrt(sqr(d[i].x)+sqr(d[i].y));
    		if (l<=r) continue;
    		double b=acos(r/l);
    		double a=atan2(d[i].y,d[i].x);
    		insert(a-b,a+b);
    	}
    	res=(ll)(n-m)*m+(ll)(n-m)*(n-m-1)/2;
    	sort(q+1,q+m+1,cmpq);
    	for (int i=1;i<=m;++i)
    		p[i]=&q[i].x,p[m+i]=&q[i].y;
    //	for (int i=1;i<=m;++i)
    //		printf("%lf %lf
    ",q[i].x,q[i].y);
    	init(m*2);
    //	for (int i=1;i<=m;++i)
    //		printf("%d %d
    ",(int)q[i].x,(int)q[i].y);
    	for (int i=m;i>=1;--i){
    		res+=query((int)q[i].x)+(m-i)-query((int)q[i].y);
    		add((int)q[i].x);
    	}
    	return res;
    }
    int main(){
    //	freopen("in.txt","r",stdin);
    //	freopen("out.txt","w",stdout);
    	scanf("%d%lld",&n,&k);
    	for (int i=1;i<=n;++i)
    		scanf("%lf%lf",&d[i].x,&d[i].y);
    //	printf("%lld
    ",calc(1));
    //	return 0;
    //	return 0;
    	double l=0,r=2e4;
    	while (r-l>1e-9){
    		double mid=(l+r)/2;
    //		printf("%lld
    ",calc(mid));
    		if (calc(mid)>=k)
    			r=mid;
    		else
    			l=mid;
    	}
    	printf("%.8lf
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    js获取cookie
    js 获取父页元素
    【HDU4571 Travel in time】二维多状态spfa
    【HDU4360】 最短路变形
    百度人脸识别模块使用分享
    APICloud · 跨越2018,技术改变世界
    Android平台targetSdkVersion设置及动态权限
    UIPullRefreshFlash模块demo示例
    webToImage (网页转图片)模块试用分享
    生成带二维码图片并通过微信分享
  • 原文地址:https://www.cnblogs.com/jz-597/p/14006550.html
Copyright © 2011-2022 走看看