lct学习小记

前言

lctlct是我一直以来都不想接触的数据结构,就在最近,我终于把这个大坑填上了。

基本定义

边分成两种,轻边和重边。重边构成的链为重链,重链可以只为一个点。
lctlct中,用一棵splaysplay维护一条重链上的点,对于每一条轻边,必定有一端是连向一条重链上深度最小的点的,我们将这条轻边的信息记录在该重链对应的splaysplayrootroot,具体的我们用tfaroottfaroot表示在这条重链中深度最小的点在树中的父亲。

splaysplay的中序遍历为11的点为该splay代表的重链中深度最小的点,中序遍历为22的点为 该splay代表的重链 中深度次小的点,以此类推。

faxfax为在splaysplay中的xx的父亲,若x为该splaysplayrootroot,则fax=0fax=0
splay(x,y)splay(x,y)表示在splaysplay上将xx不停上旋转直到成为y的儿子。

基本操作

1、Access(x)Access(x)表示将xx到根路径上的点全部放到一棵splay内。
2、Makeroot(x)Makeroot(x)表示使x成为它所在的树的根。
3、Cut(x,y)Cut(x,y)删除树边(x,y)(x,y)
4、Link(x,y)Link(x,y)加入树边(x,y)(x,y)

操作实现

Access(x)Access(x)
1、splay(x,0)splay(x,0),即将xx旋转至所在树的根,同时断掉在splay上与右儿子的连边,并使右儿子的tfatfa变为xx
2、令keep=x,x=tfax,执行操作1,把xx的右儿子变为keep,如此这般直至xx变成该树的根。

//我可能打的比较丑
void Access(int o)
{
    splay(o,0);
    if(tag[o])down(o);
    tfa[rs[o]]=o; fa[rs[o]]=0; rs[o]=0;
    while(fa[o]+tfa[o]!=0){
        int x=tfa[o];
        splay(x,0);
        tfa[rs[x]]=x; fa[rs[x]]=0;
        rs[x]=o; fa[o]=x; tfa[o]=0;
        o=x;
    }
}

Makeroot(x)
1、Access(x)Access(x)
2、splay(x,0)splay(x,0)
3、给xx所在的splay打上翻转标记,表示将重链上的点深度对称互换。

void Makeroot(int o)
{
    Access(o);
    splay(o,0); 
    tag[o]=1^tag[o];
}

Cut(x,y)Cut(x,y)
1,Makeroot(x)Makeroot(x)
2,Access(y)Access(y)
3,splay(y,0)splay(y,0)
4,在splaysplay上,把yy的左儿子(即x)的连边断掉。

void Cut(int x,int y)
{
    makeroot(x); access(y);
    splay(y,0);
    ls[y]=0; fa[x]=0; tfa[x]=0;
}

Link(x,y)Link(x,y)
1,Makeroot(x)Makeroot(x)
2,令tfax=ytfax=y

void Link(int x,int y)
{
    makeroot(x);
    tfa[x]=y;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值