KD_Tree再写

Insert就是垃圾!!!!!!以后只要不是强制在线就算死也不用这个辣鸡玩意儿!!!!

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,cnt;
namespace KD_Tree
{
    int dim;
    priority_queue<ll,vector<ll>,greater<ll> >q;
    void mdf(ll x){q.push(x);q.pop();}
    struct Point
    {
        ll P[2];
        int ls,rs;
        ll mn[2],mx[2];
    }c[100010];
    bool cmp(Point a,Point b){return a.P[dim]<b.P[dim];}
    ll sqr(ll x) {return x*x;}
    ll calc(Point x,Point y){return sqr(x.P[0]-y.P[0])+sqr(x.P[1]-y.P[1]);}
    void update(int x)
    {
        c[x].mn[0]=c[x].mx[0]=c[x].P[0];
        c[x].mn[1]=c[x].mx[1]=c[x].P[1];
        for(int i=0;i<2;i++)
        {
            if(c[x].ls)
            {
                c[x].mn[i]=min(c[x].mn[i],c[c[x].ls].mn[i]);
                c[x].mx[i]=max(c[x].mx[i],c[c[x].ls].mx[i]);
            }
            if(c[x].rs)
            {
                c[x].mn[i]=min(c[x].mn[i],c[c[x].rs].mn[i]);
                c[x].mx[i]=max(c[x].mx[i],c[c[x].rs].mx[i]);
            }
        }
    }
    int build(int l,int r,int w)
    {
        if(l>r) return 0;
        if(l==r) {update(l);return l;}
        dim=w;int mid=(l+r)>>1;
        nth_element(c+l,c+mid,c+r+1,cmp);
        c[mid].ls=build(l,mid-1,w^1);c[mid].rs=build(mid+1,r,w^1);
        update(mid);
        return mid;
    }
    ll cheque(int x,Point p)
    {
        ll tx=max(sqr(c[x].mn[0]-p.P[0]),sqr(c[x].mx[0]-p.P[0]));
        ll ty=max(sqr(c[x].mn[1]-p.P[1]),sqr(c[x].mx[1]-p.P[1]));
        return tx+ty;
    }
    void qury(int x,Point p)
    {
        ++cnt;
        mdf(calc(c[x],p));
        ll dl=0,dr=0;
        if(c[x].ls) dl=cheque(c[x].ls,p);
        if(c[x].rs) dr=cheque(c[x].rs,p);
        if(dl>dr)
        {
            if(dl>q.top()) qury(c[x].ls,p);
            if(dr>q.top()) qury(c[x].rs,p);
        }
        else
        {
            if(dr>q.top()) qury(c[x].rs,p);
            if(dl>q.top()) qury(c[x].ls,p);
        }
    }
}
using namespace KD_Tree;
int main()
{
    freopen("3.in","r",stdin);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=2*k;i++) q.push(0);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&c[i].P[0],&c[i].P[1]);
    }
    int rt=build(1,n,0);
    for(int i=1;i<=n;i++)
    {
        qury(rt,c[i]);
    }
    printf("%lld\n",q.top());
    cout<<cnt<<endl;
}
bzoj4520

 

posted @ 2018-09-26 18:20  秦こころ酱  阅读(137)  评论(0编辑  收藏  举报