社区讨论

我可能学了假的 FHQ Treap

学术版参与者 25已保存回复 43

讨论操作

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

当前回复
43 条
当前快照
1 份
快照标识符
@mi86btk3
此快照首次捕获于
2025/11/21 09:20
4 个月前
此快照最后确认于
2025/11/21 10:07
4 个月前
查看原帖
想必大佬的 merge 函数都是这么写的吧:
CPP
int merge(int x,int y)
{
	if(!x||!y)return x+y;
	if(pri[x]<pri[y]){rc[x]=merge(rc[x],y);maintain(x);return x;}
	else{lc[y]=merge(x,lc[y]);maintain(y);return y;}
}
本人对 FHQ Treap 的理解:随机优先级的存在只是为了 让合并更加随机
所以本人的 merge 函数一般是这么写的:
CPP
int merge(int x,int y)
{
    if(!x||!y)return x+y;
    if(rand()&1){rc[x]=merge(rc[x],y);maintain(x);return x;}
    else{lc[y]=merge(x,lc[y]);maintain(y);return y;}
}
这种写法让我飞到了 P3987 我永远喜欢珂朵莉~ 最优解的第二页。而据我所知,用时比我更短的评测记录大多都比我少测了几个 hack 数据。
但是,今天我做 P3960 列队 时,这种写法使我 T 成了 65 分 。下载数据后本地运行,用(递归的总次数)/(调用 mergesplit 函数的总次数) ,得出了平衡树的平均树高约为 250250 ,当我改为第一种写法时,算出的平均树高只有 3232 ,并通过了此题。
所以,请问各位大佬,我的写法有问题吗?

回复

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

正在加载回复...