替罪羊树警示后人
查看原帖
替罪羊树警示后人
1020186
zhouxianzhuo楼主2025/7/30 00:35

如果你 58 pts WA on #7~12,那大概率是你的前后缀查询出错了。

由于使用了懒删除,所以不能直接套用类似 Splay 的查询方式,因为你可能查到一个空的右儿子,导致结果为右儿子上方的实节点而非右儿子的左子树内的实节点。

如以下情况:

根为 1
1 的右儿子为 3
3 的左儿子为 2
3 为空节点

那么根据某种 Splay 查前继的方式,如果此时查 4 的前继,将会查到 1 而非 2。

错误代码:

int pre(int x,int v,int p){
	if(x==0)return p;
	if(v<=val[x])return pre(ls[x],v,p);
	if(cnt[x]>=1)p=x;
	return pre(rs[x],v,p);
}
int suf(int x,int v,int s){
	if(x==0)return s;
	if(v>=val[x])return suf(rs[x],v,s);
	if(cnt[x]>=1)s=x;
	return suf(ls[x],v,s);
}

正确代码:

int pre(int v){
	return find(rt,rnk(rt,v));
}
int suf(int v){
	return find(rt,rnk(rt,v+1)+1);
}
//此处 rnk(v) 指小于 v 的元素个数

当然,你也可以通过自己的神秘方式去正常查询,但显然不如直接套函数方便。

2025/7/30 00:35
加载中...