zoukankan      html  css  js  c++  java
  • [BZOJ4520][CQOI2016]K远点对

    bzoj
    luogu

    题意

    求欧几里德距离第(k)远点对。
    (nle10^5,klemin(frac{n(n-1)}{2},100))

    sol

    直接(kdt)了。拿一个小根堆保存最优答案,每次算出的答案和堆顶比较。
    欧几里德距离最大的估价
    (max((x-t[o].x[0])^2,(x-t[o].x[1])^2)+max((y-t[o].y[0])^2,(y-t[o].y[1])^2))

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define ll long long
    #define ls t[o].ch[0]
    #define rs t[o].ch[1]
    #define cmin(a,b) (a>b?a=b:a)
    #define cmax(a,b) (a<b?a=b:a)
    const int N = 1e5+5;
    int n,k,D,root;
    struct node{
    	int d[2];
    	bool operator < (const node &b) const
    		{return d[D]<b.d[D];}
    }a[N];
    struct kdtree{int d[2],Min[2],Max[2],ch[2];}t[N];
    priority_queue<ll,vector<ll>,greater<ll> >Q;
    ll sqr(int x){return 1ll*x*x;}
    void mt(int x,int y){
    	cmin(t[x].Min[0],t[y].Min[0]);cmax(t[x].Max[0],t[y].Max[0]);
    	cmin(t[x].Min[1],t[y].Min[1]);cmax(t[x].Max[1],t[y].Max[1]);
    }
    int build(int l,int r,int d){
    	D=d;int o=l+r>>1;
    	nth_element(a+l,a+o,a+r+1);
    	t[o].d[0]=t[o].Min[0]=t[o].Max[0]=a[o].d[0];
    	t[o].d[1]=t[o].Min[1]=t[o].Max[1]=a[o].d[1];
    	if (l<o) ls=build(l,o-1,d^1),mt(o,ls);
    	if (o<r) rs=build(o+1,r,d^1),mt(o,rs);
    	return o;
    }
    ll dist(int o,int x,int y){
    	return max(sqr(x-t[o].Min[0]),sqr(t[o].Max[0]-x))+max(sqr(y-t[o].Min[1]),sqr(t[o].Max[1]-y));
    }
    void query(int o,int x,int y){
    	ll tmp=sqr(x-t[o].d[0])+sqr(y-t[o].d[1]),d[2];
    	if (tmp>Q.top()) Q.pop(),Q.push(tmp);
    	if (ls) d[0]=dist(ls,x,y);else d[0]=0;
    	if (rs) d[1]=dist(rs,x,y);else d[1]=0;
    	tmp=d[0]>=d[1];
    	if (d[tmp]>Q.top()) query(t[o].ch[tmp],x,y);tmp^=1;
    	if (d[tmp]>Q.top()) query(t[o].ch[tmp],x,y);
    }
    int main(){
    	n=gi();k=gi()<<1;
    	for (int i=1;i<=k;++i) Q.push(0);
    	for (int i=1;i<=n;++i) a[i]=(node){gi(),gi()};
    	root=build(1,n,0);
    	for (int i=1;i<=n;++i) query(root,a[i].d[0],a[i].d[1]);
    	printf("%lld
    ",Q.top());return 0;
    }
    
  • 相关阅读:
    宏定义中的常见使用
    VS 对于LINK fatal Error 问题 解决方案
    cocos2d-x中常见的场景切换
    给新建的Cocos2d-x 3.X的Win32工程添加CocoStudio库
    2048之军衔篇 反馈 有事留言
    http 错误代码表
    华为S5700交换机初始化和配置SSH和TELNET远程登录方法
    Linux修改网卡名
    Linux如何配置bond
    linux系统下如何挂载NTFS移动硬盘
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9077920.html
Copyright © 2011-2022 走看看