您的位置:首页 > 其它

LCT细节注意

2015-11-15 10:32 295 查看
LCT的题目中经常会遇到旋根操作,那么就要打一个翻转标记,这样就会引起很多问题。

Splay的双旋

Splay必须要处理好标记下传的问题,不然由于双旋的特殊性很容易造成问题。一种比较方便的操作方式是在Splay(u)之前先把u的所有父亲的标记都下传。

void Splay(int u)
{
int top = 0;
for(int i = u;i;i = T[i].fa) Sta[++ top] = i;
for(;top;top --) Lazy_down(Sta[top]);
for(;T[u].fa;)
{
int fa = T[u].fa,ft = T[fa].fa;
if (!ft) Rotate(u,T[fa].son[1] == u); else
{
if (T[fa].son[1] == u)
{
if (T[ft].son[1] == fa) Rotate(fa,1),Rotate(u,1); else
Rotate(u,1),Rotate(u,0);
} else
if (T[ft].son[0] == fa) Rotate(fa,0),Rotate(u,0); else
Rotate(u,0),Rotate(u,1);
}
}
Update(u);
}


Link(u,v)

Link之前先判断u,v是否联通。然后必须Make_Root(v)。

bool link(int u,int v)
{
if (Root(u) == Root(v)) return 0;
Evert(v),Splay(v),Par[v] = u,Access(v);
return 1;
}


Delete(u,v)

先判联通,然后判是否相连。

bool cut(int u,int v)
{
if (Root(u) != Root(v)) return 0;
Evert(u);Access(v);Splay(v);
if (T[v].son[0] != u || T[u].son[1]) return 0;
T[v].son[0] = 0,T[u].fa = 0;Par[v] = 0;
Update(v);
return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: