社区讨论

FHQ-Treap 分裂递归瓶颈,关于递归回溯

P3369【模板】普通平衡树参与者 3已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@mdkdw45p
此快照首次捕获于
2025/07/26 23:07
7 个月前
此快照最后确认于
2025/11/04 03:40
4 个月前
查看原帖
想写详解,然后自己遇到瓶颈了(捂脸
大概是这样:
分裂模板:
C
/*
split 函数:按值分裂树
now:当前处理的节点下标
val:分裂的关键值
x:输出参数,存储所有值<=val的子树根
y:输出参数,存储所有值>val的子树根

递归地将树分裂为两部分:
x:所有值<=val的子树的根节点
y:所有值>val的子树的根节点
*/
void split(int now,int val,int &x,int &y)//直接修改外面的全局变量 x 和 y 
{
	if(!now) 
	{
		x=y=0;
		return;
	}
	if(tree[now].val<=val)//当前节点值<=val,应放入x树
	{
		
		x=now;// 当前节点作为x树的根
		split(tree[now].r,val,tree[now].r, y);//递归处理右子树,分裂点仍然是val
	} 
	else//当前节点值>val,应放入y树
	{
		
		y=now;//当前节点作为y树的根
		split(tree[now].l,val,x,tree[now].l);//递归处理左子树,分裂点仍然是val
	}
}
问题是这样的:
我现在有一棵树(圈内为权值,圈外为编号):
pVJLxiR.png
我们假设给定的 k=3k=3,为了让大家更直观体验递归过程,我挑战手算递归!
递归次数nowvalxy递归操作
第一次处理1601split(tree[1].l=2,3,x=0,tree[1].l=2)
第二次处理2222split(tree[2].r=4,3,tree[2].r=4, y=2)
第三次处理5445=tree[1].lsplit(tree[5].l=0,3,x=2,y=tree[5].l=0)
第四次处理0,return后回溯00return
第一次回溯(回到split(tree[2].r=4,3,tree[2].r=5, y)5405return
第二次回溯(回到split(tree[1].l=2,3,x=0,tree[1].l)222tree[2].y=y=4return
第三次回溯(回到split(root=3,3,x,y)16tree[1].l=x=26结束
但是回溯这边我自己都没看懂,需要更详细的说明,哪位大佬可以帮助我(就当我递归底子没打好)?

回复

8 条回复,欢迎继续交流。

正在加载回复...