LCT细节注意

来源:互联网 发布:sql declare 用法 编辑:程序博客网 时间:2024/06/04 20:11

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;    }
0 0
原创粉丝点击