传送门

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. QT各模块

    基本模块: QT core QT gui QT widgets QT multimedia QT webkit 浏览器引擎 QT network QT sql QT test 单元测试 QT webv ...

  2. TZOJ 2415 Arctic Network(最小生成树第k小边)

    描述 The Department of National Defence (DND) wishes to connect several northern outposts by a wireles ...

  3. TZOJ 3030 Courses(二分图匹配)

    描述 Consider a group of N students and P courses. Each student visits zero, one or more than one cour ...

  4. how2j学习日志——J2EE(2018年3月28日)

    1. 开始跟着站长学习J2EE,首页是简单的Tomcat安装和部署,我从官网上下载的是7.0.85版本,修改server.xml中的默认端口号为80.80端口是web服务的默认端口,因此在浏览器上输入 ...

  5. 7-OKHttp使用详解,步骤挺详细的,适合初学者使用!

    OKHttp使用详解,步骤挺详细的,适合初学者使用! 一,OKHttp介绍 okhttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Squ ...

  6. threejs- z-fighting 问题(模型的重叠部位便不停的闪烁起来。这便是Z-Fighting问题)

    Z-Buffer 在threejs中,使用深度缓冲(Z-Buffer)来完成场景可见性计算,即确定场景哪部分可见,哪部分不可见.深度缓冲(Z-Buffer)是一个二维数组,其中的每一个元素对应屏幕上的 ...

  7. 1N - 计算球体积

    根据输入的半径值,计算球的体积. Input 输入数据有多组,每组占一行,每行包括一个实数,表示球的半径. Output 输出对应的球的体积,对于每组输入数据,输出一行,计算结果保留三位小数. Sam ...

  8. CH#17C 舞动的夜晚

    原题链接 即求二分图的不可行边数量,因为不保证是完备匹配,所以需要通过网络流求出任意一组最大匹配,并建立新图判断. 建新图:对于跑完网络流的图上已经匹配的边,建立反边:对于没有匹配的边,建立正边(图只 ...

  9. java中的内存模型

    概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉害很多,该语言针对多种异构平台的平台独立性而使用的多线程技术支持也是具有开拓性的一面,有时候在开发Jav ...

  10. qrcode解决方案大全

    QRCODE解决方案 1.delphi原生QRCode.pas 2.delphi编写http服务器实现QRcode请求生成图片,http下载 3.delphi编写cgi程序,加载到apache服务器 ...