传送门

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. springmvc整合mybatis 配置文件

    使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合 ...

  2. 20 【python】入门指南:常用数据结构

    Python内置了三种高级数据结构:list,tuple,dict list:数组,相同类型的元素组成的数组 tuple:元组,相同类型的元素组成的数组,但是这里有限定条件(长度是固定的,并且值也是固 ...

  3. vue路由传值方式

    打印this.$route显示结果: 跳转路由传递参数如下 this.$router.push({ name: 'Page', query/params: { key: value }) <ro ...

  4. oracle 11g用exp无法导出空表的解决方案

    racle 11g中有个新特性,当表无数据时,不分配segment,以节省空间,当我们用exp导出空表时,无法导出. 解决方法是两个方面, 一是处理现有的空表,让其能导出: 二是设置参数,让后续的新的 ...

  5. python 常库介绍及安装方法

    bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheetahcherrypy:一个WEB frameworkctypes:用来调用动态链接库DBUtils:数 ...

  6. encode/decode/bytes

    python3中如何将字符型转换成utf-8格式的bytes类型 str_me = '字符是我'.encode('utf-8') print(str_me) >>:b'\xe5\xad\x ...

  7. ftp中ftpClient类的API

    org.apache.commons.NET.ftp  Class FTPClient类FTPClient java.lang.Object java.lang.Object继承 org.apache ...

  8. 扩展、委托、Lambda、linq

    1.扩展 扩展是一个很有用的功能.如果你有一个类.不能修改,同时你又想给他加一个方法.这个过程就是扩展.扩展就是扩展方法. 例1: 类People public class People { publ ...

  9. PAT 1071 小赌怡情(15)(代码)

    1071 小赌怡情(15 分) 常言道"小赌怡情".这是一个很简单的小游戏:首先由计算机给出第一个整数:然后玩家下注赌第二个整数将会比第一个数大还是小:玩家下注 t 个筹码后,计算 ...

  10. 洛谷1984 [SDOI2008]烧水问题

    一道找规律 原题链接 显然要将烧得的温度最大化利用,即每次都去热传递. 设水沸腾为\(x\). 第一杯直接烧水,需提高\(x\). 第二杯先与第一杯进行热传递,这样只需提高\(\dfrac{x}{2} ...