zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        return 0;
    }
    
    

    题目

    • luogu4146 天使玩偶
    • luogu4148 简单题
    • luogu3796 TATT
    • luogu4357 K远点对
    • luogu4475 巧克力王国
    • luogu4631 选圆圈
    • BZOJ3489 A RMQ Problem
  • 相关阅读:
    【Comet OJ Contest #15】孤独的吉姆 6
    【SSLOJ1467】U
    【SSLOJ1471】Y
    ajax调用webService
    泛型
    windows Server 2003 FTP
    ajax
    Linq 执行概念
    15款提高工作效率的工具分享
    Scrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发
  • 原文地址:https://www.cnblogs.com/xzyxzy/p/10206115.html
Copyright © 2011-2022 走看看