BZOJ 2648 SJY摆棋子(KD树)
【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2716
【题目大意】
给出一些点,同时不断插入点和询问某点离插入点最近距离
【题解】
我们对于给定的点直接建树,之后动态插入查询即可,重建会超时,
直接插入就可以过了
【代码】
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1500000,INF=1e9;
inline 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;
}
namespace KD_Tree{
struct Dot{
int d[2],mn[2],mx[2],l,r,sz;
Dot(){l=r=0;}
Dot(int x,int y){d[0]=x;d[1]=y;l=r=sz=0;}
int& operator [] (int x){return d[x];}
};
int D,pt[N],dcnt=0;
Dot T[N],p[N];
bool operator<(Dot a,Dot b){return a[D]<b[D];}
inline void umax(int&a,int b){if(a<b)a=b;}
inline void umin(int&a,int b){if(a>b)a=b;}
inline bool cmp(int x,int y){return T[x][D]<T[y][D];}
inline void up(int x){
T[x].sz=T[T[x].l].sz+T[T[x].r].sz+1;
T[x].mn[0]=T[x].mx[0]=T[x][0];
T[x].mn[1]=T[x].mx[1]=T[x][1];
if(T[x].l){
umax(T[x].mx[0],T[T[x].l].mx[0]);
umin(T[x].mn[0],T[T[x].l].mn[0]);
umax(T[x].mx[1],T[T[x].l].mx[1]);
umin(T[x].mn[1],T[T[x].l].mn[1]);
}
if(T[x].r){
umax(T[x].mx[0],T[T[x].r].mx[0]);
umin(T[x].mn[0],T[T[x].r].mn[0]);
umax(T[x].mx[1],T[T[x].r].mx[1]);
umin(T[x].mn[1],T[T[x].r].mn[1]);
}
}
inline int NewDot(int x,int y){
++dcnt; pt[dcnt]=dcnt;
T[dcnt][0]=x; T[dcnt][1]=y;
return up(dcnt),dcnt;
}
void AddDot(int x,int y){
++dcnt; pt[dcnt]=dcnt;
p[dcnt][0]=x; p[dcnt][1]=y;
}
// 曼哈顿距离估价函数
inline int dist(int p1,int px,int py){
int dis=0;
if(px<T[p1].mn[0])dis+=T[p1].mn[0]-px;
if(px>T[p1].mx[0])dis+=px-T[p1].mx[0];
if(py<T[p1].mn[1])dis+=T[p1].mn[1]-py;
if(py>T[p1].mx[1])dis+=py-T[p1].mx[1];
return dis;
}
//查询(px,py)最近点距离
int ans=0;
inline void ask(int x,int px,int py){
int dl,dr,d0=abs(T[x][0]-px)+abs(T[x][1]-py);
if(d0<ans)ans=d0;
dl=T[x].l?dist(T[x].l,px,py):INF;
dr=T[x].r?dist(T[x].r,px,py):INF;
if(dl<dr){
if(dl<ans)ask(T[x].l,px,py);
if(dr<ans)ask(T[x].r,px,py);
}else{
if(dr<ans)ask(T[x].r,px,py);
if(dl<ans)ask(T[x].l,px,py);
}
}
int query(int x,int px,int py){
ans=INF; ask(x,px,py);
return ans;
}
void Insert(int&x,int D,const Dot&p){
if(!x){x=NewDot(p.d[0],p.d[1]);return;}
if(p.d[D]<T[x][D])Insert(T[x].l,D^1,p);
else Insert(T[x].r,D^1,p);
up(x);
}
// 建树
int build(int l,int r,int now){
int mid=(l+r)>>1;
D=now;
nth_element(p+l,p+mid,p+r+1);
T[mid]=p[mid];
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,now^1);
if(r>mid)T[mid].r=build(mid+1,r,now^1);
return up(mid),mid;
}
// 暴力重构
int Rebuild(int l,int r,int now){
if(l>r)return 0;
int mid=(l+r)>>1,x;
D=now;
nth_element(pt+l,pt+mid,pt+r+1,cmp);
x=pt[mid];
T[x].l=Rebuild(l,mid-1,now^1);
T[x].r=Rebuild(mid+1,r,now^1);
return up(x),x;
}
}
int n,m,x,y,root=0,c;
int main(){
n=read(); m=read();
for(int i=1;i<=n;i++)KD_Tree::AddDot(read(),read());
root=KD_Tree::build(1,KD_Tree::dcnt,0);
while(m--){
if(read()==1)KD_Tree::Insert(root,0,KD_Tree::Dot(read(),read()));
else printf("%d\n",KD_Tree::query(root,read(),read()));
// if(KD_Tree::dcnt%5000==0)root=KD_Tree::Rebuild(1,KD_Tree::dcnt,0);
// 重构会超时,不重构能过
}return 0;
}
BZOJ 2648 SJY摆棋子(KD树)的更多相关文章
- bzoj 2648 SJY摆棋子 kd树
题目链接 初始的时候有一些棋子, 然后给两种操作, 一种是往上面放棋子. 另一种是给出一个棋子的位置, 问你离它最近的棋子的曼哈顿距离是多少. 写了指针版本的kd树, 感觉这个版本很好理解. #inc ...
- bzoj 2648 SJY摆棋子 —— K-D树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 学习资料:https://blog.csdn.net/zhl30041839/arti ...
- BZOJ 2648: SJY摆棋子(K-D Tree)
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 6051 Solved: 2113[Submit][Status][Discuss] Descript ...
- BZOJ 2648: SJY摆棋子
2648: SJY摆棋子 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2968 Solved: 1011[Submit][Status][Disc ...
- BZOJ 2648: SJY摆棋子 kdtree
2648: SJY摆棋子 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=2648 Description 这天,SJY显得无聊.在家自己玩 ...
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 Time Limit: 20 Sec Memory Limit: 128 MB Description 这天,S ...
- BZOJ 2648 SJY摆棋子(KD Tree)
http://www.lydsy.com/JudgeOnline/problem.php?id=2648 题意: 思路: KDtree模板题. 参考自http://www.cnblogs.com/ra ...
- bzoj 2648 SJY摆棋子——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2648 第一道KDtree! 学习资料:https://blog.csdn.net/zhl30 ...
- bzoj 2648: SJY摆棋子【KD-tree】
其实理论上cdq更优 核心是依次取x值.y值的mid作为当前节点,向两边递归建立二叉树,树上维护size:子树大小:mx[0/1]:子树内最大x/y:mn[0/1]:子树内最小x/y:d[0/1]:这 ...
随机推荐
- sql_injection之post注入
1.代码篇 </html> <center> <form action="#" method="post"> 姓名:< ...
- 20155303 实验二 Java面向对象程序设计
20155303 实验二 Java面向对象程序设计 目录 一.单元测试和TDD 任务一:实现百分制成绩转成"优.良.中.及格.不及格"五级制成绩的功能 任务二:以TDD的方式研究学 ...
- linux中core dump开启使用教程【转】
转自:http://www.111cn.net/sys/linux/67291.htm 一.什么是coredump 我们经常听到大家说到程序core掉了,需要定位解决,这里说的大部分是指对应程序由于各 ...
- 高性能.NET MVC之QMVC!
ASP.NET!这个词代表者一个单词Fat!因为他总是捆绑着太多的太多的类,太多太多的各种功能!你也许会用到,如果你反编译或阅读他们开源的源码,你会不会犹如在大海中找不到方向?不管是Web form ...
- bzoj 1083 繁忙的都市
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1083 题解: 在bzoj里能遇到如此如此水的题真是不容易…… 乍一看好像有点吓人,其实是一 ...
- pip install 升级时候 出现报asciii码错误的问题。
原因是pip安装python包会加载我的用户目录,我的用户目录恰好是中文的,ascii不能编码.解决办法是: python目录 Python27\Lib\site-packages 建一个文件site ...
- MyEclipse文本对比界面样式修改
MyEclipse刚安装好,使用文件对比的时候,发现两边的对比颜色非常浅,不同的地方不容易发现,可以通过以下配置将显示颜色调深一点. 配置 效果
- Zookeeper安装以及配置说明(三)
Zookeeper的安装和配置非常的简单,既可以配置成单机模式,也可以配置成集群模式.如下图所示: 下面将分别进行介绍: 单机模式 下载最新稳定版本zookeeper的安装包之后(看第一篇博文), 解 ...
- SQL SERVER 断开所有连接(转)
通过sql server management studio对数据进行管理,比如数据库改名等,经常遇到有正在运行的连接,以致无法操作,这时候断掉所有的连接很有必要.代码如下:(会断掉某个库的所有连接, ...
- Oracle学习笔记:parallel并行处理
在使用oracel查询时,可以通过并行提高查询速度.例如: ) from table_name a; 强行启用并行度来执行当前SQL.加上这个说明之后,可以强行启用Oracle的多线程处理功能,提高效 ...