题目大意:维护一个二维平面,平面上初始有 N 个点,支持两种操作:平面加点、查询距离某个指定点的最小哈密顿距离。

题解:学习到了 kd-tree 数据结构。

kd-tree 类似于平衡树,即:每个节点都维护了一个点坐标的信息和一个矩形区间的边界,与线段树的 leafy tree 性质不同。不过,由于 kd-tree 不涉及旋转以及维护的矩形区域的分割特征,可以使用 pushup 操作进行上传边界信息。kd-tree 的查询优化算法核心思想基于估价函数的设计,估价函数一般是某一个区域的最优解,即:若某个区域的最优解都不能对答案产生影响,那么直接忽略这块区域即可,这样就可以使得时间复杂度降低,从而达到优化的目的。时间复杂度为 \(O(\sqrt(n))\),目前不会证明。。

update at 2019.3.17

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
const int inf=0x3f3f3f3f;
const double alpha=0.75; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} int n,m;
struct node{
#define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
int p[2],x[2],y[2],ch[2],size;
}t[maxn<<1];
int root,d,ans,id[maxn],tot;
inline bool cmp(int x,int y){return t[x].p[d]<t[y].p[d];}
inline int getdis(int o,int x,int y){
return max(t[o].x[0]-x,0)+max(x-t[o].x[1],0)+max(t[o].y[0]-y,0)+max(y-t[o].y[1],0);
}
inline void pushup(int o){
t[o].x[0]=min(min(t[ls(o)].x[0],t[rs(o)].x[0]),t[o].p[0]);
t[o].x[1]=max(max(t[ls(o)].x[1],t[rs(o)].x[1]),t[o].p[0]);
t[o].y[0]=min(min(t[ls(o)].y[0],t[rs(o)].y[0]),t[o].p[1]);
t[o].y[1]=max(max(t[ls(o)].y[1],t[rs(o)].y[1]),t[o].p[1]);
t[o].size=t[ls(o)].size+t[rs(o)].size+1;
}
int build(int l,int r,int now){
if(l>r)return 0;
int mid=l+r>>1;
d=now,nth_element(id+l,id+mid,id+r+1,cmp);
ls(id[mid])=build(l,mid-1,now^1),rs(id[mid])=build(mid+1,r,now^1);
return pushup(id[mid]),id[mid];
}
inline bool isbad(int o){return (double)max(t[ls(o)].size,t[rs(o)].size)>alpha*t[o].size;}
void dfs(int o){if(o)dfs(ls(o)),id[++tot]=o,dfs(rs(o));}
void insert(int &o,int p[2],int now){
if(!o){
o=++n,t[o].p[0]=p[0],t[o].p[1]=p[1],pushup(o);
return;
}
else if(t[o].p[now]<=p[now])insert(rs(o),p,now^1);
else insert(ls(o),p,now^1);
pushup(o);
if(isbad(o))tot=0,dfs(o),o=build(1,tot,now);
}
void query(int o,int x,int y){
int dn=abs(x-t[o].p[0])+abs(y-t[o].p[1]),dl,dr;
ans=min(ans,dn);
dl=ls(o)?getdis(ls(o),x,y):inf;
dr=rs(o)?getdis(rs(o),x,y):inf;
if(dl<dr){
if(dl<ans)query(ls(o),x,y);
if(dr<ans)query(rs(o),x,y);
}else{
if(dr<ans)query(rs(o),x,y);
if(dl<ans)query(ls(o),x,y);
}
} void read_and_parse(){
t[0].x[0]=t[0].y[0]=inf,t[0].x[1]=t[0].y[1]=-inf;
n=read(),m=read();
for(int i=1;i<=n;i++)t[i].p[0]=read(),t[i].p[1]=read(),id[++tot]=i;
root=build(1,n,0);
} void solve(){
int p[2];
while(m--){
int opt=read(),x=read(),y=read();
if(opt==1)p[0]=x,p[1]=y,insert(root,p,0);
else ans=inf,query(root,x,y),printf("%d\n",ans);
}
} int main(){
read_and_parse();
solve();
return 0;
}

【BZOJ2648】SJY摆棋子的更多相关文章

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

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

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

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

  3. Bzoj2648 SJY摆棋子

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

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

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

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

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

  6. 2019.01.14 bzoj2648: SJY摆棋子(kd-tree)

    传送门 kd−treekd-treekd−tree模板题. 题意简述:支持在平面上插入一个点,求对于一个点的最近点对. 思路:cdqcdqcdq是一种很不错的分治方法 只是好像码量有点窒息 所以我用了 ...

  7. KDTree(Bzoj2648: SJY摆棋子)

    题面 传送门 KDTree 大概就是一个分割\(k\)维空间的数据结构,二叉树 建立:每层选取一维为关键字,把中间的点拿出来,递归左右,有个\(STL\)函数nth_element可以用一下 维护:维 ...

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

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

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

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

  10. 【BZOJ2648】SJY摆棋子(KD-Tree)

    [BZOJ2648]SJY摆棋子(KD-Tree) 题面 BZOJ Description 这天,SJY显得无聊.在家自己玩.在一个棋盘上,有N个黑色棋子.他每次要么放到棋盘上一个黑色棋子,要么放上一 ...

随机推荐

  1. VS2010、VS2012、VS2013、VS2015、VS2017各版本产品激活秘钥

    Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Visual Studio 2017(VS201 ...

  2. 11.13 Daily Scrum

    今天在实现餐厅列表时,原来使用的百度地图poi搜索接口无法返回餐厅的具体信息. 经过一番周折,找到了一个返回餐厅url的接口.我们调整了一下实现,在点击餐厅列表的某一项点击直接跳到和该餐厅信息有关的网 ...

  3. java面对对象(六)--内部类、匿名内部类

    内部类 可以在一个类的内部定义另一个类这种类成为内部类或嵌套类,比如: class Outer{ … class Inner{ …. } } class Outer1{} // 这个Inner1不是O ...

  4. git 使用ssh密钥

    一.查看仓库支持的传输协议 1.1查看仓库支持的传输协议 使用命令 git remote -v 查看你当前的 remote url root@zengyue:/home/yuanGit# git re ...

  5. IE下JS保存图片

    function ieSave()                   {                       var img = document.images[0];            ...

  6. [转帖]Linux内核为大规模支持100Gb/s网卡准备好了吗?并没有

    Linux内核为大规模支持100Gb/s网卡准备好了吗?并没有 之前用 千兆的机器 下载速度 一般只能到 50MB 左右 没法更高 万兆的话 可能也就是 200MB左右的速度 很难更高 不知道后续的服 ...

  7. [转帖]召冠总的 SQLSERVER常用的性能诊断语句. --保存学习备查

    CopyFrom https://www.cnblogs.com/zhaoguan_wang /*常规服务器动态管理对象包括:dm_db_*:数据库和数据库对象dm_exec_*:执行用户代码和关联的 ...

  8. Qt__主窗口、菜单和工具条(QMainWindow,QMenu,QToolBar)

    转自豆子空间 主窗口 Qt的GUI程序有一个常用的顶层窗口,叫做MainWindow.MainWindow继承自QMainWindow.QMainWindow窗口分成几个主要的区域: 最上面是Wind ...

  9. SAP PP顾问面试题及资料

    SAP PP顾问面试试题及资料 1.主数据 组织架构 •SAP中主要的组织架构有哪些?哪些用于PP的组织架构?•成本控制范围.公司代码.估价范围.工厂.库存地点之间的关系 物料主数据 •不同的物料主数 ...

  10. pandas聚合aggregate

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/5/24 15:03 # @Author : zhang chao # @Fi ...