zoukankan      html  css  js  c++  java
  • Luogu3721[AH2017/HNOI2017]单旋

    Luogu3721[AH2017/HNOI2017]单旋

    题面:洛谷

    解析:

    考虑模拟题中所述单旋过程,会发现对于一次旋转的操作,就是把它的儿子和父亲接起来,把它置为当前根的父亲,成为新根,用LCT维护即可,而对于插入操作,开一个(set),查询前驱后继即可,代码细节较多。

    代码

    // luogu-judger-enable-o2
    #include<set>
    #include<map>
    #include<cstdio>
    #include<cstring>
    #define I inline void
    #define lc c[x][0]
    #define rc c[x][1]
    #define N 100005
    using namespace std;
    int m;
    set<int> Set;
    map<int,int> mp;
    int c[N][2],f[N],r[N],sz[N];
    inline int In(){
        char c=getchar(); int x=0,ft=1;
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
        for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
        return x*ft;
    }
    inline bool nrt(int x){
        return c[f[x]][0]==x||c[f[x]][1]==x;
    }
    I PushUp(int x){
        sz[x]=sz[lc]+sz[rc]+1;
    }
    I PushDown(int x){
        if(r[x]){ swap(lc,rc); r[lc]^=1; r[rc]^=1; r[x]=0; }
    }
    I rotate(int x){
        int y=f[x],z=f[y],k=c[y][1]==x,w=c[x][!k];
        if(nrt(y)) c[z][c[z][1]==y]=x; c[x][!k]=y; c[y][k]=w;
        if(w) f[w]=y; f[y]=x; f[x]=z; PushUp(y);
    }
    I PushAll(int x){
        if(nrt(x)) PushAll(f[x]);
        PushDown(x);
    }
    I splay(int x){
        PushAll(x); int y;
        while(nrt(x)){
            if(nrt(y=f[x])) rotate((c[f[y]][1]==y)^(c[y][1]==x)?x:y);
            rotate(x);
        }
        PushUp(x);
    }
    I access(int x){
        for(int y=0;x;x=f[y=x]) splay(x),rc=y,PushUp(x);
    }
    I makeroot(int x){
        access(x); splay(x); r[x]^=1;
    }
    I split(int x,int y){
        makeroot(x); access(y); splay(y);
    }
    I link(int x,int y){
        makeroot(x); f[x]=y;
    }
    I cut(int x,int y){
        split(x,y); f[x]=c[y][0]=0; PushUp(y);
    }
    int rt,tot=0,fa[N],ls[N],rs[N];
    I Splay_insert(int x){
        int p=++tot; mp[x]=p;
        if(Set.empty()){ Set.insert(x); rt=p; puts("1"); return; }
        set<int> :: iterator it=Set.upper_bound(x);
        if(it==Set.end()||ls[mp[*it]]){
            --it; int k=mp[*it]; fa[p]=k; rs[k]=p; link(p,k);
        }
        else{ int k=mp[*it]; fa[p]=k; ls[k]=p; link(p,k); }
        Set.insert(x); split(p,rt); printf("%d
    ",sz[rt]);
    }
    I Splay_min(){
        set<int> :: iterator it=Set.begin();
        int p=mp[*it]; if(p==rt){ puts("1"); return; }
        split(p,rt); printf("%d
    ",sz[rt]);
        cut(p,fa[p]); if(rs[p]) cut(p,rs[p]),link(rs[p],fa[p]);
        ls[fa[p]]=rs[p]; if(rs[p]) fa[rs[p]]=fa[p];
        link(p,rt); fa[rt]=p; fa[p]=0; rs[p]=rt; rt=p;
    }
    I Splay_max(){
        set<int> :: iterator it=--Set.end();
        int p=mp[*it]; if(p==rt){ puts("1"); return; }
        split(p,rt); printf("%d
    ",sz[rt]);
        cut(p,fa[p]); if(ls[p]) cut(p,ls[p]),link(ls[p],fa[p]);
        rs[fa[p]]=ls[p]; if(ls[p]) fa[ls[p]]=fa[p];
        link(p,rt); fa[rt]=p; fa[p]=0; ls[p]=rt; rt=p;
    }
    I Del_min(){
        set<int> :: iterator it=Set.begin();
        int p=mp[*it];
        if(p==rt){
            if(rs[rt]) cut(rt,rs[rt]);
            rt=rs[rt]; fa[rt]=0;
            Set.erase(it); puts("1"); return;
        }
        split(p,rt); printf("%d
    ",sz[rt]);
        cut(p,fa[p]); if(rs[p]) cut(p,rs[p]),link(rs[p],fa[p]);
        ls[fa[p]]=rs[p]; if(rs[p]) fa[rs[p]]=fa[p]; Set.erase(it);
    }
    I Del_max(){
        set<int> :: iterator it=--Set.end();
        int p=mp[*it];
        if(p==rt){
            if(ls[rt]) cut(rt,ls[rt]);
            rt=ls[rt]; fa[rt]=0;
            Set.erase(it); puts("1"); return;
        }
        split(p,rt); printf("%d
    ",sz[rt]);
        cut(p,fa[p]); if(ls[p]) cut(p,ls[p]),link(ls[p],fa[p]);
        rs[fa[p]]=ls[p]; if(ls[p]) fa[ls[p]]=fa[p]; Set.erase(it);
    }
    int main(){
        m=In();
        for(int i=1,op,key;i<=m;++i){
            op=In();
            if(op==1) key=In(),Splay_insert(key);
            if(op==2) Splay_min();
            if(op==3) Splay_max();
            if(op==4) Del_min();
            if(op==5) Del_max();
        }
        return 0;
    }
    
  • 相关阅读:
    python三大神器之virtualenv pip, virtualenv, fabric通称为pythoner的三大神器。
    pip使用国内镜像,豆瓣、清华
    pip国内源
    Android原生(Native)C开发之四:SDL移植笔记
    libcurl使用easy模式阻塞卡死等问题的完美解决
    linux 自定义信号
    ubuntu 12.04安装telnet和ssh服务
    libcurl with telnet
    ubuntu使用ssh登入不执行.bashrc解决方法
    pthread_kill
  • 原文地址:https://www.cnblogs.com/pkh68/p/10520006.html
Copyright © 2011-2022 走看看