zoukankan      html  css  js  c++  java
  • BZOJ4520 CQOI2016K远点对(KD-Tree+堆)

      堆维护第k大,每个点KD-Tree上A*式查询较远点,跑得飞快,复杂度玄学。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,c,root,cnt;
    struct point
    {
        int d[2];
        bool operator <(const point&a) const
        {
            return d[c]<a.d[c];
        }
    }a[N];
    struct KDTree{int ch[2],a[2][2];point p;
    }tree[N];
    priority_queue<ll,vector<ll>,greater<ll> > q;
    ll sqr(int x){return 1ll*x*x;}
    ll dis(point u,point v){return sqr(u.d[0]-v.d[0])+sqr(u.d[1]-v.d[1]);}
    ll dis(point u,int a[2][2]){return sqr(max(u.d[0]-a[0][0],a[0][1]-u.d[0]))+sqr(max(u.d[1]-a[1][0],a[1][1]-u.d[1]));}
    void build(int &k,int l,int r,int op)
    {
        if (l>r) return;
        k=++cnt,c=op;int mid=l+r>>1;nth_element(a+l,a+mid,a+r+1);
        tree[k].p=a[mid];tree[k].a[0][0]=tree[k].a[0][1]=a[mid].d[0],tree[k].a[1][0]=tree[k].a[1][1]=a[mid].d[1];
        for (int i=l;i<=r;i++)
        tree[k].a[0][0]=min(tree[k].a[0][0],a[i].d[0]),tree[k].a[0][1]=max(tree[k].a[0][1],a[i].d[0]),
        tree[k].a[1][0]=min(tree[k].a[1][0],a[i].d[1]),tree[k].a[1][1]=max(tree[k].a[1][1],a[i].d[1]);
        build(tree[k].ch[0],l,mid-1,op^1);
        build(tree[k].ch[1],mid+1,r,op^1);
    }
    void query(int k,point p)
    {
        if (dis(tree[k].p,p)>=q.top()) q.push(dis(tree[k].p,p)),q.pop();
        int l=tree[k].ch[0],r=tree[k].ch[1];ll u=dis(p,tree[l].a),v=dis(p,tree[r].a);
        if (u<v) swap(l,r),swap(u,v);
        if (l&&u>=q.top()) query(l,p);
        if (r&&v>=q.top()) query(r,p);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4520.in","r",stdin);
        freopen("bzoj4520.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read()<<1;
        for (int i=1;i<=n;i++) a[i].d[0]=read(),a[i].d[1]=read();
        build(root,1,n,0);
        while (m--) q.push(0);
        for (int i=1;i<=n;i++) query(root,a[i]);
        cout<<q.top();
        return 0;
    }
  • 相关阅读:
    软件的结构
    SpringMVC返回值类型及响应数据类型
    mybatis学习日记3
    面试八
    面试七
    微信小程序实例源码大全下载
    dot.js模板引擎,避免大量拼接字符串
    前端重构方案了解一下
    微信小程序开发基础教程
    如何让签到成为提升用户活跃度的利器
  • 原文地址:https://www.cnblogs.com/Gloid/p/10161753.html
Copyright © 2011-2022 走看看