之前以为很恐怖,学了之后发现没有想象中的难

关键还是长长见识,了解能够应用的方面

 

两个题单,慢慢刷:

hwzzyr - Lct系列小结

FlashHu - LCT总结——应用篇(附题单)

 

目前的模板:

(UPD:2020.8.13更新,针对多测优化了一下)

const int N=300005;

//在struct外遍历树上节点一定要pushdown! 
struct LinkCutTree
{
    int fa[N],ch[N][2];
    bool isroot[N];
    int rev[N];
    
    void init(int n)
    {
        for(int i=1;i<=n;i++)
            fa[i]=ch[i][0]=ch[i][1]=rev[i]=0,isroot[i]=true;
    }
    
    void pushdown(int x)
    {
        int &l=ch[x][0],&r=ch[x][1];
        if(rev[x])
        {
            swap(l,r);
            rev[l]^=1;
            rev[r]^=1;
            rev[x]=0;
        }
    }
    
    //取决于要维护的东西 看是否要pushdown两层 
    void push(int x)
    {
        if(!isroot[x])
            push(fa[x]);
        pushdown(x);
    }
    
    //维护Splay中的信息 
    void pushup(int x)
    {
        /*维护子树/连通块大小 
        if(x)
            sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+si[x]+1;*/
    }
    
    void rotate(int x)
    {
        int f=fa[x],ff=fa[f];
        int dir=(ch[f][1]==x);
        swap(isroot[x],isroot[f]);
        
        if(!isroot[x])
            ch[ff][ch[ff][1]==f]=x;
        fa[x]=ff;
        
        ch[f][dir]=ch[x][dir^1];
        fa[ch[x][dir^1]]=f;
        
        ch[x][dir^1]=f;
        fa[f]=x;
        
        pushup(f),pushup(x);
    }
    
    void splay(int x)
    {
        push(x);
        
        while(!isroot[x])
        {
            int f=fa[x],ff=fa[f];
            if(!isroot[f])
                rotate((ch[f][1]==x)==(ch[ff][1]==f)?f:x);
            rotate(x);
        }
    }
    
    //访问x 返回新根 
    int access(int x)
    {
        int y=0;
        while(x)
        {
            splay(x);
            
            //si[x]=si[x]-sz[y]+sz[ch[x][1]];//维护子树/连通块大小 
            isroot[ch[x][1]]=true;
            isroot[ch[x][1]=y]=false;
            
            pushup(y),pushup(x);
            y=x,x=fa[x];
        }
        return y; 
    }
    
    //将x置为根 
    void makeroot(int x)
    {
        access(x);
        splay(x);
        rev[x]^=1;
    }
    
    //连接x,y 
    void link(int x,int y)
    {
        makeroot(x);
        //makeroot(y);//维护子树/连通块大小
        fa[x]=y;
        //si[y]+=sz[x];//维护子树/连通块大小
        pushup(y);
    }
    
    //断开x,y 
    void cut(int x,int y)
    {
        makeroot(x);
        access(y);
        splay(y);
        
        fa[x]=ch[y][0]=0;
        isroot[x]=true;
        
        pushup(y);
    }
    
    //判断x,y是否相连 
    bool same(int x,int y)
    {
        makeroot(x);
        while(fa[y])
            y=fa[y];
        return x==y;
    }
};
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-01-10
  • 2021-12-26
  • 2021-07-07
猜你喜欢
  • 2022-12-23
  • 2021-09-05
  • 2021-05-19
  • 2022-12-23
  • 2021-08-03
  • 2022-12-23
  • 2018-08-10
相关资源
相似解决方案