zoukankan      html  css  js  c++  java
  • BZOJ 2648 SJY摆棋子 ——KD-Tree

    【题目分析】

        KD-Tree第一题,其实大概就是搜索剪枝的思想,在随机数据下可以表现的非常好NlogN,但是特殊数据下会达到N^2。

        精髓就在于估价函数get以及按照不同维度顺序划分的思想。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
     
    #include <set>
    #include <map>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <queue>
     
    using namespace std;
     
    #define maxn 1000005
    #define inf 1e9
     
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
     
    struct node{
        int mn[2],mx[2],d[2],l,r;
        int operator [] (int x) {return d[x];}
        void init() {d[0]=read(); d[1]=read();}
    }t[maxn],now;
     
    int root,D,n,m,tot=0,ans;
     
    int dis(node a,node b){return abs(a[1]-b[1])+abs(a[0]-b[0]);}
     
    bool operator < (node a,node b){return a[D]<b[D]||(a[D]==b[D]&&a[D^1]<b[D^1]);}
     
    void update(int k)
    {
        for (int i=0;i<2;++i)
        {
            t[k].mn[i]=min(t[k][i],min(t[t[k].l].mn[i],t[t[k].r].mn[i]));
            t[k].mx[i]=max(t[k][i],max(t[t[k].l].mx[i],t[t[k].r].mx[i]));
        }
    }
     
    int build(int l,int r,int dir)
    {
        int mid=(l+r)/2;
        D=dir;
        nth_element(t+l,t+mid,t+r+1);
        for (int i=0;i<2;++i) t[mid].mn[i]=t[mid].mx[i]=t[mid][i];
        if (l<mid) t[mid].l=build(l,mid-1,dir^1);
        if (r>mid) t[mid].r=build(mid+1,r,dir^1);
        update(mid);
        return mid;
    }
     
    void ins(int & k,int dir)
    {
        if (!k)
        {
            k=++tot;
            t[k]=now;
            for (int i=0;i<2;++i) t[k].mn[i]=t[k].mx[i]=t[k][i];
            return ;
        }
        if (now[dir]<t[k][dir]||(now[dir]==t[k][dir]&&now[dir^1]<t[k][dir^1])) ins(t[k].l,dir^1);
        else ins(t[k].r,dir^1);
        update(k);
    }
     
    int get(int k)
    {
        if (!k) return inf;
        int ret=0;
        for (int i=0;i<2;++i) ret+=max(0,t[k].mn[i]-now[i]);
        for (int i=0;i<2;++i) ret+=max(0,now[i]-t[k].mx[i]);
        return ret;
    }
     
    void query(int k)
    {
        int dl=get(t[k].l),dr=get(t[k].r),d0=dis(t[k],now);
        ans=min(ans,d0);
        if (dl<dr)
        {
            if (dl<ans) query(t[k].l);
            if (dr<ans) query(t[k].r);
        }
        else
        {
            if (dr<ans) query(t[k].r);
            if (dl<ans) query(t[k].l);
        }
    }
     
    int main()
    {
        for (int i=0;i<2;++i) t[0].mn[i]=inf,t[0].mx[i]=-inf;
        n=read();m=read();tot=n;
        for (int i=1;i<=n;++i) t[i].init();
        root=build(1,n,0);
        while (m--)
        {
            int opt=read();
            now.init();
            if (opt==1) ins(root,0);
            else
            {
                ans=inf;
                query(root);
                printf("%d
    ",ans);
            }
        }
    }
    

      

  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6195044.html
Copyright © 2011-2022 走看看