KD-tree学习笔记

KD-tree学习笔记

Tags:数据结构



超好理解直接看代码吧

// luogu-judger-enable-o2
#include<iostream>
#include<algorithm>
#define lc t[x].ch[0]
#define rc t[x].ch[1]
using namespace std;
int read()
{
    char ch=getchar();int h=0;
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
    return h;
}
void Max(int &a,int b) {if(b>a) a=b;}
void Min(int &a,int b) {if(b<a) a=b;}
const double o_o=0.75;
const int N=5e5+10;
int n,m,D,Q[N<<1],top,ans,cnt,nod,rt;
struct Node{int d[2];}a[N<<1];
struct KDtree
{
    int d[2],mn[2],mx[2],ch[2],siz;
    void reset() {d[0]=d[1]=mn[0]=mn[1]=mx[0]=mx[1]=ch[0]=ch[1]=siz=0;}
    inline void Get(Node a)
        {
            mn[0]=mx[0]=d[0]=a.d[0];
            mn[1]=mx[1]=d[1]=a.d[1];
        }
}t[N<<1];
int operator < (Node a,Node b) {return a.d[D]<b.d[D];}
int New()
{
    int x=!top?++nod:Q[top--];
    t[x].reset();return x;
}
void upd(int x,int y)
{
    for(int i=0;i<=1;i++)
        Min(t[x].mn[i],t[y].mn[i]),Max(t[x].mx[i],t[y].mx[i]);
}
void pushup(int x)
{
    t[x].siz=t[lc].siz+t[rc].siz+1;
    if(lc) upd(x,lc);if(rc) upd(x,rc);
}
int Build(int l,int r,int nD)
{
    int mid=(l+r)>>1,x=New();D=nD;
    nth_element(a+l,a+mid,a+r+1);//把第mid大的放在第mid个位置,并且左边都比它小,右边都比它大
    t[x].Get(a[mid]);
    if(l<mid) lc=Build(l,mid-1,nD^1);
    if(r>mid) rc=Build(mid+1,r,nD^1);
    pushup(x);return x;
}
void pia(int x)
{
    if(lc) pia(lc);
    a[++cnt]=(Node){t[x].d[0],t[x].d[1]};
    Q[++top]=x;
    if(rc) pia(rc);
}
void check(int &x,int nD)
{
    if(max(t[lc].siz,t[rc].siz)>t[x].siz*o_o)
        cnt=0,pia(x),x=Build(1,cnt,nD);
}
void Insert(int &x,Node a,int nD)
{
    if(!x) {t[x=New()].Get(a);return;}
    if(a.d[nD]<=t[x].d[nD]) Insert(lc,a,nD^1);
    else Insert(rc,a,nD^1);
    pushup(x);check(x,nD);
}
int Dis(int x,int X,int Y)
{
    return max(t[x].mn[0]-X,0)+max(X-t[x].mx[0],0)+
        max(t[x].mn[1]-Y,0)+max(Y-t[x].mx[1],0);
}
void Query(int x,int xx,int yy)
{
    int L=abs(t[x].d[0]-xx)+abs(t[x].d[1]-yy),d[2];
    d[0]=lc?Dis(lc,xx,yy):2e9;
    d[1]=rc?Dis(rc,xx,yy):2e9;
    Min(ans,L);L=d[1]<d[0];
    if(d[L]<ans) Query(t[x].ch[L],xx,yy);
    if(d[L^1]<ans) Query(t[x].ch[L^1],xx,yy);
}
int main()
{
    cin>>n>>m;cnt=n;
    for(int i=1;i<=n;i++) a[i].d[0]=read(),a[i].d[1]=read();
    rt=Build(1,n,0);
    for(int t=1;t<=m;t++)
    {
        int op=read(),x=read(),y=read();
        if(op==1) Insert(rt,(Node){x,y},0);
        else ans=2e9,Query(rt,x,y),printf("%d\n",ans);
    }
    return 0;
}

题目

  • luogu4146 天使玩偶
  • luogu4148 简单题
  • luogu3796 TATT
  • luogu4357 K远点对
  • luogu4475 巧克力王国
  • luogu4631 选圆圈
  • BZOJ3489 A RMQ Problem
posted @ 2019-01-01 21:32  饕餮传奇  阅读(419)  评论(0编辑  收藏  举报