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

    kd-tree

    #include<bits/stdc++.h>
    #define lc (ch[x][0])
    #define rc (ch[x][1])
    #define ll long long
    using namespace std;
    const int maxn=1e6+4;
    int n,m,cnt;
    ll mn[maxn][2],mx[maxn][2],ch[maxn][2],sz[maxn];
    int nthdir;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    inline ll sq(ll x){
        return (ll)x*x;
    }
    struct Point{
        ll pos[2];
        ll& operator [](ll x){
            return pos[x];
        }
        bool operator < (const Point &t) const {
            return pos[nthdir] < t.pos[nthdir];
        }
        ll operator - (const Point &t) const {
            return sq(abs(pos[0]-t.pos[0]))+sq(abs(pos[1]-t.pos[1]));
        }
        Point(int x,int y){
            pos[0]=x;pos[1]=y;
        }
        Point(){};
    }p[maxn];
    inline void pushup(int x){
        for(int i=0;i<=1;i++){
            mn[x][i]=mx[x][i]=p[x][i];
            if(lc){
                mn[x][i]=min(mn[x][i],mn[lc][i]);
                mx[x][i]=max(mx[x][i],mx[lc][i]);
            }
            if(rc){
                mn[x][i]=min(mn[x][i],mn[rc][i]);
                mx[x][i]=max(mx[x][i],mx[rc][i]);
            }
        }
        sz[x]=sz[lc]+sz[rc]+1;
    }
    inline int build(int l,int r,int dir){
        nthdir=dir;
        int x=(l+r)>>1;
        nth_element(p+l,p+x,p+r+1);
        mn[x][0]=mx[x][0]=p[x][0];
        mn[x][1]=mx[x][1]=p[x][1];
        if(l<x) lc=build(l,x-1,dir^1);
        if(r>x) rc=build(x+1,r,dir^1);
        pushup(x);return x;
    }
    inline ll calc(int x,Point P){
        return max(sq(mn[x][0]-P[0]),sq(mx[x][0]-P[0]))+max(sq(mn[x][1]-P[1]),sq(mx[x][1]-P[1]));
    }
    inline void query(int x,Point P){
        ll h=P-p[x];
        if(h>q.top()){
            q.pop();
            q.push(h);
        }
        ll l=0,r=0;
        if(lc) l=calc(lc,P);
        if(rc) r=calc(rc,P);
        if(l>r){
            if(l>q.top()) query(lc,P);
            if(r>q.top()) query(rc,P);
        }else{
            if(r>q.top()) query(rc,P);
            if(l>q.top()) query(lc,P);
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d%d",&p[i][0],&p[i][1]);
        cnt=n;
        int rt=build(1,n,0);
        for(int i=1;i<=m*2;i++) q.push(0);
        for(int i=1;i<=n;i++){
            query(rt,p[i]);
        }
        cout<<q.top();
        return 0;
    }
  • 相关阅读:
    我向老师问声好
    创业的27个真相:破釜沉舟时,要先学会潜水
    印象品牌:成功的标志
    稻盛和夫:打造两个世界500强的强者思维
    假如我们不曾相逢
    让我的诗句带走你的空虚
    昨日的誓言
    假如我有一百万
    我把我的青春献给你
    代腾飞(一读者为IT诗人代腾飞名字作诗)
  • 原文地址:https://www.cnblogs.com/wifimonster/p/10509898.html
Copyright © 2011-2022 走看看