luogu P6224 [BJWC2014]数据 KD-tree 标准板子 重构+二维平面内最近最远距离查询
LINK:数据
这是一个我写过的最标准的板子。
重构什么的写的非常的标准 常数应该也算很小的。
不过虽然过了题 我也不知道代码是否真的无误 反正我已经眼查三遍了...
重构:建议先插入 插入过程中找到第一个不平衡的点再重构。
最小距离查询剪枝:当前坐标为mn和mx中间的时候显然 最小距离可能为0 否则 为他们其中之一和当前坐标的差。
最大距离查询剪枝:当前坐标和mn以及mx的最大距离差。
const int MAXN=500010,K=2;
const db alpha=0.75;
int n,root,top,D,Q,cnt,ans;
struct wy
{
int d[K];
int mn[K],mx[K];
int sz,l,r;
}t[MAXN];
int q[MAXN];
inline int cmp(int a,int b){return t[a].d[D]<t[b].d[D];}
inline void update(int x)
{
sz(x)=sz(l(x))+sz(r(x))+1;
for(int i=0;i<K;++i)
{
if(l(x))t[x].mx[i]=max(t[x].mx[i],t[l(x)].mx[i]),t[x].mn[i]=min(t[x].mn[i],t[l(x)].mn[i]);
if(r(x))t[x].mx[i]=max(t[x].mx[i],t[r(x)].mx[i]),t[x].mn[i]=min(t[x].mn[i],t[r(x)].mn[i]);
}
}
inline int build(int l,int r,int k)
{
if(l>r)return 0;
int mid=(l+r)>>1;D=k;
nth_element(q+l,q+mid,q+1+r,cmp);
int x=q[mid];
for(int i=0;i<K;++i)t[x].mx[i]=t[x].mn[i]=t[x].d[i];
l(x)=build(l,mid-1,(k+1)%K);
r(x)=build(mid+1,r,(k+1)%K);
update(x);return x;
}
inline void erase(int x)
{
if(!x)return;q[++top]=x;
erase(l(x));erase(r(x));
}
inline void rebuild(int &x,int k)
{
top=0;erase(x);
x=build(1,top,k);
}
inline void insert(int &p,int k,int flag)
{
if(!p)
{
p=++cnt;sz(p)=1;
for(int i=0;i<K;++i)t[p].mx[i]=t[p].mn[i]=t[p].d[i]=q[i];
return;
}
int mark=0;
if(q[k]<t[p].d[k])
{
if((sz(l(p))+1)>=alpha*(sz(p)+1))mark=1;
insert(l(p),(k+1)%K,flag|mark);
}
else
{
if((sz(r(p)+1)>=alpha*(sz(p)+1)))mark=1;
insert(r(p),(k+1)%K,flag|mark);
}
if(!flag&&mark)rebuild(p,k);
update(p);
}
inline int dis(int x)
{
int cnt=0;
rep(0,K-1,i)cnt+=abs(t[x].d[i]-q[i]);
return cnt;
}
inline int dismin(int x)//查当前离节点最近的距离
{
int cnt=0;
rep(0,K-1,i)if(q[i]<t[x].mn[i])cnt+=t[x].mn[i]-q[i];
else if(q[i]>t[x].mx[i])cnt+=q[i]-t[x].mx[i];
return cnt;
}
inline void ask_min(int x)
{
ans=min(ans,dis(x));
int L=dismin(l(x));
int R=dismin(r(x));
if(L<R)
{
if(L<ans&&l(x))ask_min(l(x));
if(R<ans&&r(x))ask_min(r(x));
}
else
{
if(R<ans&&r(x))ask_min(r(x));
if(L<ans&&l(x))ask_min(l(x));
}
}
inline int dismax(int x)
{
int cnt=0;
rep(0,K-1,i)cnt+=max(abs(q[i]-t[x].mn[i]),abs(q[i]-t[x].mx[i]));
return cnt;
}
inline void ask_max(int x)
{
ans=max(ans,dis(x));
int L=dismax(l(x));
int R=dismax(r(x));
if(L>R)
{
if(L>ans&&l(x))ask_max(l(x));
if(R>ans&&r(x))ask_max(r(x));
}
else
{
if(R>ans&&r(x))ask_max(r(x));
if(L>ans&&l(x))ask_max(l(x));
}
}
int main()
{
freopen("1.in","r",stdin);
get(n);cnt=n;
rep(1,n,i)
{
int get(x);int get(y);
t[i].d[0]=x;t[i].d[1]=y;
q[i]=i;
}
root=build(1,n,0);
get(Q);
rep(1,Q,i)
{
int op;
get(op);get(q[0]);get(q[1]);
if(op==0)insert(root,0,0);
if(op==1)
{
ans=INF;
ask_min(root);
put(ans);
}
if(op==2)
{
ans=-INF;
ask_max(root);
put(ans);
}
}
return 0;
}
luogu P6224 [BJWC2014]数据 KD-tree 标准板子 重构+二维平面内最近最远距离查询的更多相关文章
- K-D TREE算法原理及实现
博客转载自:https://leileiluoluo.com/posts/kdtree-algorithm-and-implementation.html k-d tree即k-dimensional ...
- BZOJ4520:[CQOI2016]K远点对(K-D Tree)
Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...
- k-d tree算法
k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...
- BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)
Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏- ...
- [转载]kd tree
[本文转自]http://www.cnblogs.com/eyeszjwang/articles/2429382.html k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据 ...
- 【数据结构与算法】k-d tree算法
k-d tree算法 k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点 ...
- 【数据结构】K-D Tree
K-D Tree 这东西是我入坑 ICPC 不久就听说过的数据结构,但是一直没去学 QAQ,终于在昨天去学了它.还是挺好理解的,而且也有用武之地. 目录 简介 建树过程 性质 操作 例题 简介 K-D ...
- k-d tree 学习笔记
以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...
- [luogu P2633] Count on a tree
[luogu P2633] Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点 ...
随机推荐
- 状压DP之愤怒的小鸟
题目 传送们P2831 题目较长,不加以赘述 直接步入正题 首先是数学知识,我们可以先根据给出的任意两只猪构建相应的抛物线,同时再构建完之后应判断抛物线的合法性(比如a小于0啊,等等),公式推演就不在 ...
- JAVA服务实例内存高问题排查及解决
生产服务内存高问题 问题描述 1."计算中心" 服务在生产环境运行一段时间后,实际占用内存4.8G,业务运行正常,未出现OOM.(本文以此服务进行排查) 2.生产环境的老项目,均出 ...
- pythonl操作数据库
目录 今日内容详细 Navicat软件 提示 练习题 pymysql模块 sql注入 navicat可视化界面操作数据库 数据库查询题目讲解(多表操作) python如何操作MySQL(pymysql ...
- 开源导入导出库Magicodes.IE 多sheet导入教程
原文作者:tanyongzheng 多Sheet导入教程 说明 本教程主要说明如何使用Magicodes.IE.Excel完成多个Sheet数据的Excel导入. 要点 多个相同格式的Sheet数据导 ...
- Mysql基础(十一):Self Join
Summary: 如何使用 MySQL self join 进行表的 自己对自己的join操作.. 前面的教程,已经教过join语法,都是两个表的之间的操作,特殊的,当一个表自己和自己进行join,那 ...
- web 部署专题(四):压力测试(二)压力测试实例 flask 四种wsgi方式对比(tornado,Gunicorn,Twisted,Gevent)
使用工具:siege 代码结构: hello.py templates |--hello.html hello.py代码: from flask import Flask, render_templa ...
- 李航统计学习方法(第二版)(五):k 近邻算法简介
1 简介 k近邻法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类.k近邻法假设给定一个训练数据集,其中的实例类别已定.分类时,对新的实例,根据其k个最近邻的训练实例的类别,通 ...
- 数据可视化之PowerQuery篇(六)PowerQuery技巧:批量合并Excel表的指定列
本文来源于一个星友的问题,他有上百个Excel表格,格式并不完全一样,列的位置顺序也不同,但每个表都有几个共同列,这种情况下,能不能通过Power Query把这些表格共同的列批量合并呢? 当然是可以 ...
- ”initialization failure:0x0000000C“错误,何解?
今天开机后打开软件,报出这样的警告”initialization failure:0x0000000C“. 我问了度娘,看了很多回答,答案参差不齐.其中,有个回答还是很不错的(刚好我的是win10系统 ...
- Eclipse普通java Project文件路径问题
Eclipse普通java Project文件路径问题 项目的结构如图 读取src里某个包下的文件,代码如下 BufferedReader br=new BufferedReader(new File ...