zoukankan      html  css  js  c++  java
  • KDtree模板

    模板题:luogu4169  有个点要吸氧才能过

    #include<bits/stdc++.h>
    using namespace std;
    const double alpha=0.8;
    const int M=3;
    const int N=3000010;
    const int inf=0x3f3f3f3f;
    int WD=2,now;
    int cnt,ans;
    int Q[N],B,A;
    int n,m,root;
    int bad,badfa,badwd;
    struct Point{
        int x[M];
    }P[N];
    struct Tree{
        int l,r;
        int siz;
        int MIN[M],MAX[M];
        Point p; 
    }T[N];
    bool operator <(Point A,Point B){
        return A.x[now]<B.x[now];
    }
    int newpoint(Point p){
        int pos=0;
        if(B)pos=Q[B--];
        else pos=++cnt;
        T[pos].l=T[pos].r=T[pos].siz=0;
        T[pos].p=p;
        return pos;
    }
    void update(int pos){
        for(int i=0;i<WD;i++){
            T[pos].MAX[i]=T[pos].MIN[i]=T[pos].p.x[i];
            if(T[pos].l){
                T[pos].MIN[i]=min(T[pos].MIN[i],T[T[pos].l].MIN[i]);
                T[pos].MAX[i]=max(T[pos].MAX[i],T[T[pos].l].MAX[i]);
            }
            if(T[pos].r){
                T[pos].MIN[i]=min(T[pos].MIN[i],T[T[pos].r].MIN[i]);
                T[pos].MAX[i]=max(T[pos].MAX[i],T[T[pos].r].MAX[i]);
            }
        }
        T[pos].siz=T[T[pos].l].siz+T[T[pos].r].siz+1;
        return;
    }
    int build(int l,int r,int wd){
        if(l>r)return 0;
        int mid=(l+r)/2;
        now=wd;
        nth_element(P+l,P+mid,P+r+1);
        int pos=newpoint(P[mid]);
        T[pos].l=build(l,mid-1,(wd+1)%WD);
        T[pos].r=build(mid+1,r,(wd+1)%WD);
        update(pos);
        return pos;
    }
    bool check(int pos){
        if(1ll*T[pos].siz*alpha<1ll*T[T[pos].l].siz)return 0;
        if(1ll*T[pos].siz*alpha<1ll*T[T[pos].r].siz)return 0;
        return 1;
    }
    void pia(int pos,int num){
        if(T[pos].l)pia(T[pos].l,num);
        P[++A]=T[pos].p;
        Q[++B]=pos;
        if(T[pos].r)pia(T[pos].r,T[T[pos].l].siz+1+num);
    }
    void rebuild(){
        if(!bad)return;
        int next=(T[badfa].r==bad?1:0),last=bad;
        A=0;pia(bad,0);bad=build(1,A,badwd);
        if(next==0)T[badfa].l=bad;
        else T[badfa].r=bad;
        if(last==root)root=bad;
    }
    int Ins(int pos,Point p,int wd,int fa){
        if(!pos){
            pos=newpoint(p);
            update(pos);
            return pos;
        }
        if(p.x[wd]<T[pos].p.x[wd]){
            T[pos].l=Ins(T[pos].l,p,(wd+1)%WD,pos);
        }else{
            T[pos].r=Ins(T[pos].r,p,(wd+1)%WD,pos);    
        }
        update(pos);
        if(!check(pos)){
            bad=pos;
            badfa=fa;
            badwd=wd;
        }
        return pos;
    }
    void Insert(Point p){
        bad=badfa=0;
        root=Ins(root,p,0,0);
        rebuild();
    }
    int dist(Point A,Point B){
        int res=0;
        for(int i=0;i<WD;i++)res+=abs(A.x[i]-B.x[i]);
        return res;
    }
    int getdist(Point A,int pos){
        int res=0;
        for(int i=0;i<WD;i++){
            res+=max(0,A.x[i]-T[pos].MAX[i]);
            res+=max(0,T[pos].MIN[i]-A.x[i]);
        }
        return res;
    }
    void query(int pos,Point p){
        ans=min(ans,dist(p,T[pos].p));
        int Ldist=inf,Rdist=inf;
        if(T[pos].l)Ldist=getdist(p,T[pos].l);
        if(T[pos].r)Rdist=getdist(p,T[pos].r);
        if(Ldist<Rdist){
            if(Ldist<ans)query(T[pos].l,p);
            if(Rdist<ans)query(T[pos].r,p);
        }else{
            if(Rdist<ans)query(T[pos].r,p);
            if(Ldist<ans)query(T[pos].l,p);    
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            int X,Y;
            scanf("%d%d",&X,&Y);
            P[i].x[0]=X;
            P[i].x[1]=Y;
        }
        root=build(1,n,0);
        for(int i=1;i<=m;i++){
            Point tmp;
            int opt;
            scanf("%d%d%d",&opt,&tmp.x[0],&tmp.x[1]);
            if(opt==1){
                Insert(tmp);
            }else{
                ans=inf;
                query(root,tmp);
                printf("%d
    ",ans);
            }
        }
    }
    KDtree
  • 相关阅读:
    python学习笔记(29)-操作excel
    python学习笔记(28)-unittest单元测试-执行用例
    python学习笔记(27)-unittest单元测试-测试用例
    python学习笔记(26)-request模块
    python学习笔记(25)-继承
    c++ 流基本概念
    友元函数、类和运算符重载
    c++中的引用
    c++重点知识点
    指针和结构体
  • 原文地址:https://www.cnblogs.com/passione-123456/p/12252910.html
Copyright © 2011-2022 走看看