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]:这 ...
随机推荐
- C. Polygon for the Angle(几何)
题目链接:http://codeforces.com/contest/1096/problem/C 题目大意:T是测试样例,然后每一次输入一个角度,然后问你在一个n边形里面,能不能构成这个角度,如果能 ...
- WeX5入门之欢乐捕鱼打包
一.下载欢乐捕鱼的素材包 https://files.cnblogs.com/files/wordblog/%E7%B4%A0%E6%9D%90.zip 二.把欢乐捕鱼素材放入项目中 并启动tomca ...
- 图片压缩之 PNG
作者:程志达链接:https://zhuanlan.zhihu.com/p/19570424来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. PNG(Portable N ...
- 无需登录-悟空CRM 存储型XSS
无需登录-悟空CRM 存储型XSS 审计悟空的缘由是看见某云爆出CRM的getshell,于是就想着去挖出来瞅瞅!但可能自己把自己给局限了,就想着去挖那些无限制访问的文件. 故事的发生点 漏洞文件:/ ...
- 某大型网络社区传播性XSS分析
某大型网络社区传播性XSS分析 这个XSS存在于天涯某个不起眼的子论坛,通过发布新帖子可以触发. 漏洞分析 论坛针对XSS有一定过滤措施,例如转义单双引号,过滤左右尖括号等等.所 ...
- 2016.6.19——C++杂记
C++杂记 补充的小知识点: 1.while(n--)和while(--n)区别: while(n--)即使不满足也执行一次循环后跳出. while(--n)不满足直接跳出循环,不执行语句. 用cou ...
- Office DDE漏洞学习笔记
1.前言 2017年下半年爆发出来的Office漏洞,一直没有空做笔记记录.在病毒分析中也看到有利用这个漏洞的样本,针对Office系列软件发起的钓鱼攻击和APT攻击一直是安全攻防的热点. 2.off ...
- node练习笔记
一.用http模块实现客户端 1. 这个错误的原因是:客户端http_client.js里面的端口和服务端里面的端口不一样 2.querystring.stringify 字符串转换成对象 q ...
- 从源码层次分析asterisk如何产生呼叫
老规矩,看别人是怎么搞的 http://blog.chinaunix.net/uid-14723273-id-1739552.html over...
- Linux基础 - tmux
安装 yum install tmux 类似vim当中存在命令行模式以及编辑模式,从编辑模式进入命令行模式需要先按ESC键,在tmux当中进行操作也要先准备好"姿势"再操作,默认情 ...