zoukankan      html  css  js  c++  java
  • 【bzoj4520】 Cqoi2016—K远点对

    http://www.lydsy.com/JudgeOnline/problem.php?id=4520 (题目链接)

    题意

      求平面内第K远点对的距离。

    Solution

      左转题解:jump

    细节

      刚开始我还开了两个堆,想想其实是没必要的→_→

      距离什么的开LL

    代码

    // bzoj4520
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=100010;
    int n,m,D,K,rt;
    priority_queue<LL,vector<LL>,greater<LL> > q;
    
    struct KDtree {
    	int l,r,v[2],mn[2],mx[2];
    	friend bool operator < (const KDtree a,const KDtree b) {
    		return a.v[D]<b.v[D];
    	}
    }tr[maxn],S;
    
    void update(int k) {
    	for (int i=0;i<=1;i++) {
    		if (tr[k].l) {
    			tr[k].mn[i]=min(tr[k].mn[i],tr[tr[k].l].mn[i]);
    			tr[k].mx[i]=max(tr[k].mx[i],tr[tr[k].l].mx[i]);
    		}
    		if (tr[k].r) {
    			tr[k].mn[i]=min(tr[k].mn[i],tr[tr[k].r].mn[i]);
    			tr[k].mx[i]=max(tr[k].mx[i],tr[tr[k].r].mx[i]);
    		}
    	}
    }
    int build(int l,int r,int p) {
    	D=p;
    	int mid=(l+r)>>1;
    	nth_element(tr+l,tr+mid,tr+r+1);
    	if (l<mid) tr[mid].l=build(l,mid-1,p^1);
    	if (r>mid) tr[mid].r=build(mid+1,r,p^1);
    	update(mid);
    	return mid;
    }
    LL dis(LL x1,LL y1,LL x2,LL y2) {
    	return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    }
    LL eva(int k) {
        LL lu=dis(S.v[0],S.v[1],tr[k].mn[0],tr[k].mn[1]);
        LL ru=dis(S.v[0],S.v[1],tr[k].mx[0],tr[k].mn[1]);
        LL ld=dis(S.v[0],S.v[1],tr[k].mn[0],tr[k].mx[1]);
        LL rd=dis(S.v[0],S.v[1],tr[k].mx[0],tr[k].mx[1]);
        return max(max(lu,ru),max(ld,rd));
    }
    void query(int k) {
    	if (!k) return;
    	LL d=dis(S.v[0],S.v[1],tr[k].v[0],tr[k].v[1]);
    	if (q.top()<d) q.pop(),q.push(d);
    	LL dl=eva(tr[k].l),dr=eva(tr[k].r);
    	if (dl>dr) {
    		if (q.top()<dl) query(tr[k].l);
    		if (q.top()<dr) query(tr[k].r);
    	}
    	else {
    		if (q.top()<dr) query(tr[k].r);
    		if (q.top()<dl) query(tr[k].l);
    	}
    }
    	
    int main() {
    	scanf("%d%d",&n,&K);
    	for (int i=1;i<=n;i++) {
    		scanf("%d%d",&tr[i].v[0],&tr[i].v[1]);
    		tr[i].mn[0]=tr[i].mx[0]=tr[i].v[0];
    		tr[i].mn[1]=tr[i].mx[1]=tr[i].v[1];
    	}
    	rt=build(1,n,0);
    	for (int i=1;i<=2*K;i++) q.push(0);
    	for (int i=1;i<=n;i++) S=tr[i],query(rt);
    	printf("%lld",q.top());
    	return 0;
    }
    

      

  • 相关阅读:
    oracle中rownum和rowid的区别和用法
    jsp中,对window对象的简单总结
    下拉列表框实现二级联动
    window.showModalDialog()的简单用法
    javascript中的正则表达式
    java实现树型结构样式
    几个数据库的驱动、连接
    Java桌面程序中设置一个软件的系统托盘
    【动态规划】求两字符串连续最大公共子串长度
    大整数相乘
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6264045.html
Copyright © 2011-2022 走看看