汇总犯过的一大堆神奇错误。
访问儿子结点时,没有pushDown()
,左右儿子未翻转。
例:
Node *findRoot(Node *u)
{
Access(u);
Splay(u);
//这里漏掉一句:u->pushDown();
while(u->ch[0]!=null)
{
u=u->ch[0];
u->pushDown();
}
return u;
}
解决方法:
写完后搜索所有->ch
,检查是否之前已pushDown()
pushUp()
更新时,儿子结点未更新,仍存在懒标记
解决方法:
使
u
u
u结点懒标记意义表示
u
u
u的儿子结点需更新,而不是
u
u
u需要更新。
###懒标记下传后未清空
例:
void pushDown()
{
ch[0]->Update(add,rev);
ch[1]->Update(add,rev);
//漏了以下两句
//add=0;
//rev=false;
}
自定义空指针null
内部信息错误
例:
null->fa=null->ch[0]=null->ch[1]=null;
null->siz=1;//这里应=0
Cut操作判断删除的u->v边是否存在时,判断错误
例:
void Cut(Node *u,Node *v)
{
makeRoot(u);
Access(v);
Splay(u);
u->pushDown();
if(u->ch[1]!=v)//还需判断 ||v->siz!=1
return;
u->setChild(null,1);
v->fa=null;
}
用翻转懒标记更新时,直接将标记改为true
,没有取反
void Update(bool re)
{
if(this==null)
return;
if(re)
{
swap(ch[0],ch[1]);
rev=true;//应为rev^=1
}
}
FindRoot后没有Splay,导致复杂度变高
Node *Root(Node *u)
{
Access(u);
Splay(u);
u->PushDown();
while(u->son[0]!=null)
u=u->son[0],u->PushDown();
//少了Splay(u);
return u;
}