• LCT总结


    最近在机房呆的时间蛮多
    所以就有时间把以前学的算法复习一下
    像lct这种代码量大且不好理解的代码,
    一定要及时复习

    以前写的模板,多少有些缺陷
    所以这次整理了一个优美的

    tip

    快要考试,我们的目标是:不掉人品,踏实肯干

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    const int N=1000005;
    int n,m,root,cnt;
    int size[N],mx[N],pre[N],v[N],ch[N][2],q[N];
    bool rev[N];
    struct node{
        int x,y,nxt;
    };
    node way[N<<1];
    int st[N],tot=0;
    
    int get(int x)
    {
        return ch[pre[x]][0]==x ? 0:1;
        //x是爸爸哪个孩子 
    }
    
    int isroot(int x)
    {
        return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x;
        //判断该节点是不是根 
    }
    
    void update(int x)  //这里我维护的是子树大小 
    {
        size[x]=1;
        if (ch[x][0]) size[x]+=size[ch[x][0]];
        if (ch[x][1]) size[x]+=size[ch[x][1]];
    } 
    
    void push(int x)  //一般是用来处理翻转操作的 
    {
        if (x&&rev[x])
        {
            rev[x]^=1;
            if (ch[x][0]) rev[ch[x][0]]^=1;
            if (ch[x][1]) rev[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    } 
    
    void rotate(int x)
    {
        int fa=pre[x];
        int grand=pre[fa];
        int wh=get(x);
        if (!isroot(fa)) ch[grand][ch[grand][0]==fa? 0:1]=x;
        //爸爸不是根,那么一定有爷爷 
        ch[fa][wh]=ch[x][wh^1];  //爸爸和儿子的关系一定对应好 
        pre[ch[fa][wh]]=fa;
        pre[x]=grand; pre[fa]=x;
        ch[x][wh^1]=fa;
        update(fa);
        update(x);
    }
    
    void splay(int x)
    {
        int top=0;
        q[++top]=x;
        for (int i=x;!isroot(i);i=pre[i])   //把该节点到根的所有节点入队 
            q[++top]=pre[i];   //pre[i]
        while (top) push(q[top--]);   //全部push
        for (int fa;!isroot(x);rotate(x))
            if (!isroot(fa=pre[x])) 
                rotate(get(fa)==get(x)? fa:x);
    }
    
    void expose(int bh)
    {
        int t=0;
        while (bh)
        {
            splay(bh);
            ch[bh][1]=t;   //expose后节点的右儿子就没了 
            update(bh);   //产生了一个新儿子,所以需要update 
            t=bh;
            bh=pre[bh];
        }
    }
    
    void makeroot(int bh)
    {
        expose(bh);
        splay(bh);
        rev[bh]^=1;   //把x换到根上,那么ta以上的节点深度互换 
    }
    
    void link(int x,int y)
    {
        makeroot(x);
        pre[x]=y;    //x转到根上之后链接,这样牵扯到的节点较少 
    }
    
    void cut(int x,int y)
    {
        makeroot(x);
        expose(y);
        splay(y);
        ch[y][0]=pre[x]=0;  
    }
    
    int find(int bh)
    {
        expose(bh);
        splay(bh);
        while (ch[bh][0]) bh=ch[bh][0];   //找到根节点 
        return bh;
    }
    
    int main()
    {
        //两点连通性
        if (find(x)==find(y)) printf("Yes
    ");
        //两点距离
        makeroot(x);
        expose(y);
        splay(y);
        printf("%d
    ",size[ch[y][0]]); 
        //路径上的节点权值和
        makeroot(x);
        expose(y);
        splay(y);
        printf("%d
    ",sum[y]);
        //节点到根的距离
        int ro=find(x);
        makeroot(ro);
        expose(x);
        splay(x);
        printf("%d
    ",size[ch[x][0]]);
        //更改节点值
        makeroot(x);
        v[x]=z;
        update(x); 
    }
  • 相关阅读:
    第二阶段站立会议(3)
    第二阶段站立会议(2)
    第二阶段站立会议(1)
    返回一个最大联通子数组的和
    场景调研
    课程改进意见
    百度搜索引擎——评价
    求1的个数
    《校园封神榜》个人工作总结——第十天
    《校园封神榜》个人工作总结——第九天
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673215.html
Copyright © 2020-2023  润新知