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小的点 ...
随机推荐
- 火车运输(最大生成树+lca) 洛谷P1967
货车运输 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 \(q\) 辆货车 ...
- BZOJ1854 连续攻击游戏 题解
题目 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多 ...
- Mister B and PR Shifts,题解
题目链接 分析: 题意很明白,不再多说了,直接分析题目,首先想一想暴力,直接枚举起点,然后求出来,时间复杂度n*n,显然不太好,所以我们考虑换一种方法枚举,当然本质还是枚举,其实你会发现变化i次和i+ ...
- 基层教师 - CMD命令之net命令与IPC连接
1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接: net use \ ...
- shell专题(二):Shell解析器
(1)Linux提供的Shell解析器有: [atguigu@hadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/da ...
- java 面向对象(三):类结构 属性
类的设计中,两个重要结构之一:属性 对比:属性 vs 局部变量 1.相同点: * 1.1 定义变量的格式:数据类型 变量名 = 变量值 * 1.2 先声明,后使用 * 1.3 变量都其对应的作用域 2 ...
- 01 flask源码剖析之werkzurg 了解wsgi
01 werkzurg了解wsgi 目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 1. wsgi django和flask内部都没有 ...
- Python之爬虫(七)正则的基本使用
什么是正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是 事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符”,这个“规则字符” 来表达对字符的一种过滤逻辑. 正则并不是pyth ...
- 数据可视化实例(十三): 发散型文本 (matplotlib,pandas)
偏差 (Deviation) https://datawhalechina.github.io/pms50/#/chapter11/chapter11 发散型文本 (Diverging Texts) ...
- (八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)
兴趣的朋友可以去了解一下前几篇,你的赞就是对我最大的支持,感谢大家! (一) SpringBoot起飞之路-HelloWorld (二) SpringBoot起飞之路-入门原理分析 (三) Sprin ...