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);
            }
        }
    }
    

      

  • 相关阅读:
    MQTT 连接服务端失败,报错客户机未连接(32104)
    引入其他类定义的静态变量
    Linux 中文乱码问题
    MQTT 简介
    mybatis xml 特殊字符转义
    如何科学的高效率的选择创建线程数
    【安卓自定义控件系列】自绘控件打造界面超炫功能超强的圆形进度条
    Eclipse简介和使用技巧快捷方式
    MyEclipse如何全局搜索
    JAVA面向对象-----访问修饰符
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6195044.html
Copyright © 2011-2022 走看看