传送门

kd−treekd-treekd−tree模板题。

题意简述:支持在平面上插入一个点,求对于一个点的最近点对。


思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息

所以我用了kd−treekd-treekd−tree来做。

其实就是两个维度分别作为键值来建立二叉搜索树即可。

这道题在查询时可以通过判断下一层的有没有可能对答案有贡献来剪个枝。

由于蒟蒻暂时没写过方差划分因此时间很慢。

代码:

#include<bits/stdc++.h>
#define mid (l+r>>1)
#define ri register int
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
typedef pair<int,int> pii;
const int N=1e6+5,inf=0x3f3f3f3f;
int n,m,mx[N][2],mn[N][2],son[N][2],ans,tot=0;
bool cmpdir;
struct Pot{
    int a[2];
    inline int&operator[](const int&k){return a[k];}
    inline const int&operator[](const int&k)const{return a[k];}
}p[N];
inline bool cmp(const Pot&a,const Pot&b){return a[cmpdir]<b[cmpdir];}
inline void pushup(int p){
    if(son[p][0]){
        mn[p][0]=min(mn[p][0],mn[son[p][0]][0]);
        mx[p][0]=max(mx[p][0],mx[son[p][0]][0]);
        mn[p][1]=min(mn[p][1],mn[son[p][0]][1]);
        mx[p][1]=max(mx[p][1],mx[son[p][0]][1]);
    }
    if(son[p][1]){
        mn[p][0]=min(mn[p][0],mn[son[p][1]][0]);
        mx[p][0]=max(mx[p][0],mx[son[p][1]][0]);
        mn[p][1]=min(mn[p][1],mn[son[p][1]][1]);
        mx[p][1]=max(mx[p][1],mx[son[p][1]][1]);
    }
}
inline int build(int l,int r,bool d){
    cmpdir=d;
    nth_element(p+l,p+mid,p+r+1,cmp);
    mn[mid][0]=mx[mid][0]=p[mid][0],mn[mid][1]=mx[mid][1]=p[mid][1];
    if(l<mid)son[mid][0]=build(l,mid-1,d^1);
    if(r>mid)son[mid][1]=build(mid+1,r,d^1);
    return pushup(mid),mid;
}
inline void insert(int k,Pot v,bool d){
    if(p[k][d]<=v[d]){
        if(son[k][1])insert(son[k][1],v,d^1);
        else{
            p[son[k][1]=++tot]=v;
            mx[tot][0]=mn[tot][0]=v[0];
            mx[tot][1]=mn[tot][1]=v[1];
        }
    }
    else{
        if(son[k][0])insert(son[k][0],v,d^1);
        else{
            p[son[k][0]=++tot]=v;
            mx[tot][0]=mn[tot][0]=v[0];
            mx[tot][1]=mn[tot][1]=v[1];
        }
    }
    pushup(k);
}
inline int ask(int k,Pot v){
    int ret=0;
    ret+=max(0,mn[k][0]-v[0]);
    ret+=max(0,mn[k][1]-v[1]);
    ret+=max(0,v[0]-mx[k][0]);
    ret+=max(0,v[1]-mx[k][1]);
    return ret;
}
inline int dist(Pot a,Pot b){return abs(a[0]-b[0])+abs(a[1]-b[1]);}
inline void query(int k,Pot v,bool d){
    ans=min(ans,dist(p[k],v));
    int al=inf,ar=inf;
    if(son[k][0])al=ask(son[k][0],v);
    if(son[k][1])ar=ask(son[k][1],v);
    if(al<ar){
        if(al<ans)query(son[k][0],v,d^1);
        if(ar<ans)query(son[k][1],v,d^1);
    }
    else{
        if(ar<ans)query(son[k][1],v,d^1);
        if(al<ans)query(son[k][0],v,d^1);
    }
}
int main(){
    n=read(),m=read(),tot=0;
    for(ri i=1,x,y;i<=n;++i)x=read(),y=read(),p[++tot]=(Pot){x,y};
    for(ri rt=build(1,n,0),i=1,x,y,op;i<=m;++i){
        op=read(),x=read(),y=read();
        if(op==1)insert(rt,(Pot){x,y},0);
        else ans=inf,query(rt,(Pot){x,y},0),cout<<ans<<'\n';
    }
    return 0;
}

2019.01.14 bzoj2648: SJY摆棋子(kd-tree)的更多相关文章

  1. luogu4169 [Violet]天使玩偶/SJY摆棋子 / bzoj2648 SJY摆棋子 k-d tree

    k-d tree + 重构的思想,就能卡过luogu和bzoj啦orz #include <algorithm> #include <iostream> #include &l ...

  2. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

  3. BZOJ2648: SJY摆棋子&&2716: [Violet 3]天使玩偶

    BZOJ2648: SJY摆棋子 BZOJ2716: [Violet 3]天使玩偶 BZOJ氪金无极限... 其实这两道是同一题. 附上2648的题面: Description 这天,SJY显得无聊. ...

  4. [BZOJ2648] SJY摆棋子 kd-tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 5421  Solved: 1910[Submit][Status][Disc ...

  5. Bzoj2648 SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 3128  Solved: 1067 Description 这天,SJY显得无聊.在家自己玩.在一个 ...

  6. bzoj 2648 SJY摆棋子 kd树

    题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...

  7. 【kd-tree】bzoj2648 SJY摆棋子

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  8. BZOJ2648 SJY摆棋子(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  9. [bzoj2648]SJY摆棋子(带插入kd-tree)

    解题关键:带插入kdtree模板题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

随机推荐

  1. Shell教程 之echo命令

    1.显示普通字符串 这里的双引号完全可以省略,以下命令效果一致: echo "传递参数实例!" echo 传递参数实例! 2.显示转义字符 echo "\"传递 ...

  2. oracle 修改数据精度问题

    今天,在建表后插入语句时,报了这样的错误,对于这样的错误,搜集了一些资料,进行了总结如下: 建表语句: 1 2 3 4 5 6 7 8 9 create table pre_info( pre_cod ...

  3. php的三种CLI常量:STDIN,STDOUT,STDERR

    PHP CLI(command line interface)中,有三个系统常量,分别是STDIN.STDOUT.STDERR,代表文件句柄. 应用一: <?php while($line = ...

  4. swift语言版本选择 - 解决XCode报错:The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported valu

    转发链接:https://blog.csdn.net/nathan1987_/article/details/79757368 The “Swift Language Version” (SWIFT_ ...

  5. linux下svn版本控制的常用命令大全

    1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/domain 简写:s ...

  6. YII2中使用RBAC对模块,控制器,方法的权限控制以及规则的使用

    在使用YII2中自带的RBAC时,需要先配置config/web.php: return [ // ... 'components' => [ 'authManager' => [ 'cl ...

  7. JS打开新窗口,子窗口操作父窗口

    <!--父窗口弹窗代码开始--> <script type="text/javascript"> function OpenWindow() { windo ...

  8. MVC是架构模式,而不是设计模式

    最早学编程的时候看过一些书,印象深刻的一本书<设计模式解析>,那本书给我后来的工作提供了很大的帮助. 他叫我站在问题模型的立场上指定解决方法,也教会了我软件设计中每个问题都可以细化到到不可 ...

  9. 长时间没有操作putty就会断开连接是怎么回事?

    seconds between keepalives 设置为10就好了, 这个值有什么含义,服务器为了节省资源采取了一些措施,其中一条就是如果检测一个会话(session)几分钟或者几小时没有数据流入 ...

  10. android apk 反编译过程

    一.准备必要的工具 apktool (资源文件获取) dex2jar(源码文件获取) jd-gui  (源码查看) 以上三个文件的下载地址为:https://download.csdn.net/dow ...