zoukankan      html  css  js  c++  java
  • luogu3690

    非常好的一篇博客

    写下之前自己被困住的几个点吧:

    1.access找的不是到真实的根的一条路径,而是到能找到的最上面的splay的根(makeroot同理)

    2.findroot找的是x所在原树的树根(深度最小),并旋转至当前一棵splay的根

    tips:具体的还是没特别懂,多做题吧

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define ls tr[x][0]
    #define rs tr[x][1]
    #define maxn 300002
    using namespace std;
    int n,m,res[maxn],tr[maxn][2],rev[maxn],w[maxn],tmp[maxn],f[maxn];
    inline void pushup(int x){res[x]=res[ls]^res[rs]^w[x];}
    inline void pushr(int x){swap(ls,rs);rev[x]^=1;}
    inline void pushdown(int x){if(rev[x]){if(ls)pushr(ls);if(rs)pushr(rs);rev[x]=0;}}
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    inline bool isroot(int x){return (tr[f[x]][0]==x||tr[f[x]][1]==x);}
    inline void rotate(int x){
        int fa=f[x],gfa=f[fa],whicx=tr[fa][1]==x,flag=isroot(fa);//注意flag要先赋值,因为若之后其父亲会变为x 
        tr[fa][whicx]=tr[x][whicx^1];if(tr[fa][whicx])f[tr[fa][whicx]]=fa;
        tr[x][whicx^1]=fa;f[fa]=x;
        f[x]=gfa;
        if(flag)tr[gfa][tr[gfa][1]==fa]=x;
        pushup(fa);
    }
    inline void splay(int x){
        int y=x,siz=0,z;
        tmp[++siz]=y;
        while(isroot(y))tmp[++siz]=y=f[y];
        while(siz)pushdown(tmp[siz--]);
        while(isroot(x)){
            y=f[x];z=f[y];
            if(isroot(y))rotate((tr[y][1]==x)==(tr[z][1]==y)?y:x);
            rotate(x);
        }
        pushup(x);
    }
    inline void access(int x){
        for(int y=0;x;x=f[y=x])splay(x),rs=y,pushup(x);
    }
    inline void makeroot(int x){access(x);splay(x);pushr(x);}
    inline void split(int x,int y){makeroot(x);access(y);splay(y);}
    inline int findroot(int x){
        access(x);splay(x);
        while(ls)pushdown(x),x=ls;
        return x;
    }
    inline void link(int x,int y){makeroot(x);if(findroot(y)!=x)f[x]=y;}
    inline void cut(int x,int y){
        makeroot(x);if(findroot(y)==x&&f[x]==y&&!rs){f[x]=tr[y][0]=0;pushup(y);}
    }
    int main(){
        read(n);read(m);
        int typ,x,y;
        for(int i=1;i<=n;i++)read(w[i]);
        while(m--){
            read(typ);read(x);read(y);
            switch(typ){
                case 0:split(x,y);printf("%d
    ",res[y]);break;
                case 1:link(x,y);break;
                case 2:cut(x,y);break;
                case 3:makeroot(x);w[x]=y;pushup(x);
            }
        }
    }
  • 相关阅读:
    subprocess 的 Popen用法
    subprocess之check_out用法
    Appium使用总结
    如何将pyqt5的qt-designer设计出来的 .ui 和 .qrc 文件转化成 .py 文件
    python serial模块使用,是pyserial而非serial
    基于 Tensorflow 实现 Mobilenet V1 并基于 CFAR-10 数据训练
    预测单词词性
    单词纠错系统
    Python深度学习 deep learning with Python
    书单
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9064675.html
Copyright © 2011-2022 走看看