首页 > 其他分享 >k-D Tree

k-D Tree

时间:2024-02-01 09:57:44浏览次数:35  
标签:rs int siz tr Tree ls inline

作用

维护 \(k\) 维空间上的点的数据结构,树高严格 \(log\),空间 \(O(n)\)。支持插入,并如替罪羊树一般根据“不平衡度” \(\alpha\) 重构。

可以用线段树式或平衡树式实现。

建树

对于一个给定序列,类似线段树建树,使用 nth_element 可以总复杂度 \(n\log\) 建树。

由于需要分割,要么轮流按顺序维度分割,要么按方差较大的一位分(小优化?)。

修改

单点加入

一路走到叶子,类似替罪羊的拍平。可以 \(\alpha=0.6\)。

区间修改

类似线段树,可以打标记,写 pushdown

删除节点

打标记,同时维护子树 size(未删点数),便于重构。

查询

核心是分成不交、完全计入贡献、部分有(继续递归)三个部分,类似线段树,但是复杂度玄学。

为了判断某个子树有没有进去的价值,需要 pushup 出子树内各个坐标的最值,便于判断在不在查询范围内/可能使答案更优。

代码

(杂交了一下)

带修

inline int New(node x){
	int u=hh?rub[hh--]:++tot;
	tr[u].val=x;
	tr[u].siz=1;
	tr[u].mn[0]=tr[u].mx[0]=x.px[0];
	tr[u].mn[1]=tr[u].mx[1]=x.px[1];
	tr[u].ls=tr[u].rs=0;
	return u;
}
inline void pushup(int u){
	int ls=tr[u].ls,rs=tr[u].rs;
	tr[u].siz=tr[ls].siz+tr[rs].siz+1;
	for(int i=0;i<K;++i){
		tr[u].mn[i]=tr[u].mx[i]=tr[u].val.px[i];
		if(ls){
			tr[u].mn[i]=min(tr[u].mn[i],tr[ls].mn[i]);
			tr[u].mx[i]=max(tr[u].mx[i],tr[ls].mx[i]);
		}
		if(rs){
			tr[u].mn[i]=min(tr[u].mn[i],tr[rs].mn[i]);
			tr[u].mx[i]=max(tr[u].mx[i],tr[rs].mx[i]);
		}
	}
}
inline int build(int l,int r,int d){
	int mid=l+r>>1;
	dm=d;
	nth_element(a+l,a+mid,a+r+1,cmp);
	int u=New(a[mid]);
	if(l<mid) tr[u].ls=build(l,mid-1,d^1);
	if(r>mid) tr[u].rs=build(mid+1,r,d^1);
	pushup(u);
	return u;
}
inline void pia(int u){
	if(tr[u].ls) pia(tr[u].ls);
	a[++num]=tr[u].val;
	if(tr[u].rs) pia(tr[u].rs);
	rub[++hh]=u;
}
inline void check(int &u,int d){
	if(tr[u].siz>3&&max(tr[tr[u].ls].siz,tr[tr[u].rs].siz)*5>tr[u].siz*3){
		num=0;pia(u);
		u=build(1,num,d);
	}
}
inline void insert(int &u,int d){
	if(!u){
		u=New(tx);
		return ;
	}
	if(tx.px[d]<=tr[u].val.px[d]) insert(tr[u].ls,d^1);
	else insert(tr[u].rs,d^1);
	pushup(u);check(u,d);
}

不带

inline void pushup(int u){
	int ls=tr[u].ls,rs=tr[u].rs;
	for(int i=0;i<K;++i){
		tr[u].mn[i]=tr[u].mx[i]=c[u].px[i];
		if(ls){
			tr[u].mn[i]=min(tr[u].mn[i],tr[ls].mn[i]);
			tr[u].mx[i]=max(tr[u].mx[i],tr[ls].mx[i]);
		}
		if(rs){
			tr[u].mn[i]=min(tr[u].mn[i],tr[rs].mn[i]);
			tr[u].mx[i]=max(tr[u].mx[i],tr[rs].mx[i]);
		}
	}
}
inline int build(int l,int r,int d){
	int mid=l+r>>1;
	nth_element(b+l,b+mid,b+r+1,[&](int x,int y){return c[x].px[d]<c[y].px[d];});
	int u=b[mid];
	if(l<mid) tr[u].ls=build(l,mid-1,d^1);
	if(mid<r) tr[u].rs=build(mid+1,r,d^1);
	pushup(u);
	return u;
}

模型

k近点对

矩形修,矩形查

k-D Tree分治/kdt上维护历史值

tips

下次学一下历史最大值。

标签:rs,int,siz,tr,Tree,ls,inline
From: https://www.cnblogs.com/mRXxy0o0/p/18000606

相关文章

  • Treeview
    usingDBHelper;usingSunny.UI;usingSystem;usingSystem.Collections.Generic;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.Windows.Forms;usingSystem.Linq;usingSystem.Text;namespaceMES{publicpartialclassRolePower:UIForm{......
  • Git、.gitinore、SourceTree使用介绍
    Git使用教程Git是分布式版本控制系统,也可以叫内容管理系统(CMS),工作管理系统。Git安装本文档后半部分会介绍SourceTree,SourceTree内置有Git所以这里不介绍其他Git安装方式。Git工作流程克隆Git资源到本地仓库(文件夹)在本地仓库中添加或修改文件。获取Git其他人的修改信......
  • CF337E Divisor Tree
    题意简述定义DivisorTree为一棵树:叶子上的数为质数。非叶子上的数为其所有儿子上的数的乘积。给定\(n\)个数\(a_i\),你需要让每个\(a_i\)都在DivisorTree上出现,并最小化DivisorTree的节点数量。\(n\le8,a_i\le10^6\)。分析显然DivisorTree上只能有质数......
  • abc152F - Tree and Constraints
    abc152F-TreeandConstraints题意:给定一棵树,要求对每条边染成黑色或者白色,其中有m个限制,第i个限制形如ai,bi,表示ai到bi的路径上至少有一条黑色边,求方案数。看到数据第一反应是状压,但是好像没办法搞。于是考虑容斥,能想到容斥的话就差不多做完了,每次标记一下两个点和他们的lc......
  • MFC TreeView 控件的基本认识
    ▲树控件OnInitDialog()里面的一些基础操作。BOOLCMFCApplication1Dlg::OnInitDialog(){CDialogEx::OnInitDialog();//将“关于...”菜单项添加到系统菜单中。//IDM_ABOUTBOX必须在系统命令范围内。ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTB......
  • Element Plus el-select el-tree-select 获取选中的label值
    select下拉框通过@change选择改变,轮巡方式根据id取name的值<el-form-itemlabel="企业类型"prop="entTypeId"><el-selectv-model="form.entTypeId"placeholder="请选择企业类型"style="width:220px"@change="entTypeCha......
  • el-input el-tree组件 问题:blur先于click触发怎么解决
    页面构造 使用mousedowm触发比blur更早,因为是组件所以得使用native,prevent阻止默认事件然后this.$refs.parentInput.focus();让焦点保持,点击展开或关闭箭头时候让焦点存在,点击节点的时候让页面关闭要兼容筛选效果,做了一个临时tempNode用于存放之前选择的对象,这样当在未进......
  • ARC101E Ribbons on Tree
    思路直接正着考虑合法的方案数不是很好做,那么正难则反,可以用总方案数减去不合法方案数,这样容斥一下就能得到答案了。设\(F(S)\)表示集合\(S\)中的边不被覆盖的方案数。那么最后的答案就是\(\displaystyle\sum_{S\subseteqE}(-1)^{|S|}F(S)\)。再思考\(F(S)\)怎么求。......
  • CF1917F Construct Tree
    Link:http://codeforces.com/problemset/problem/1917/F知识点:背包,构造简述\(T\)组数据,每组数据给定参数\(d\)与一长度为\(n\)的数列\(l\),仅需判断是否可以构造出一棵树,满足:树的所有边长与数列元素一一对应。树的直径为\(d\)。\(1\leT\le250\),\(2\len\le2000\)......
  • Link-cut Tree
    这可能是我第一次学数据结构如此绝望链剖分重链剖分使用静态数据结构维护实链剖分(LCT)使用splay维护对每个节点,选择一个儿子作为实边,其他为虚边实链用splay维护虚边认父不认子,连接两个splay长链剖分查询修改链上信息随意换根动态维护连通性LCT核心操作access(x)从指......