zoukankan      html  css  js  c++  java
  • [Splay]luogu P2596 书架

    https://www.luogu.org/problem/P2596

    分析

    ?我怎么又开始写水题了

    拿一个rev数组记录编号为s的书对应Splay中哪个节点

    然后top就是将对应点旋至根,将左儿子嫁接到其后继上

    bottom类似

    insert操作只需要直接交换节点与其前驱/后继的信息以及rev值

    ask将s旋到根输出左儿子大小即可

    query直接Get_Kth

    #include <iostream> 
    #include <cstdio>
    using namespace std;
    const int N=8e4+10;
    struct Node {
        int c[2],sz,id,f;
    }t[N];
    int rt,cnt;
    int n,m,rev[N];
    
    void Update(int x) {t[x].sz=t[t[x].c[0]].sz+t[t[x].c[1]].sz+1;}
    
    bool Witch(int x) {return t[t[x].f].c[1]==x;}
    
    void Rotate(int x) {
        int f=t[x].f,gf=t[f].f,lr=Witch(x);
        t[x].f=gf;if (gf) t[gf].c[Witch(f)]=x;
        t[f].c[lr]=t[x].c[lr^1];if (t[x].c[lr^1]) t[t[x].c[lr^1]].f=f;
        t[t[f].f=x].c[lr^1]=f;
        Update(f);Update(x);
    }
    
    void Splay(int x) {
        for (int f=t[x].f;f;Rotate(x),f=t[x].f)
            if (t[f].f) Rotate(Witch(x)==Witch(f)?f:x);
        rt=x;
    }
    
    int Get_Kth(int x,int k) {
        if (t[t[x].c[0]].sz+1>k) return Get_Kth(t[x].c[0],k);
        if (t[t[x].c[0]].sz+1==k) return x;
        return Get_Kth(t[x].c[1],k-t[t[x].c[0]].sz-1);
    }
    
    void Add(int val) {
        t[++cnt]=(Node){0,0,1,val,0};rev[val]=cnt;
        if (cnt<2) {
            rt=cnt;
            return;
        }
        t[t[cnt-1].c[1]=cnt].f=cnt-1;Update(cnt-1);
        Splay(cnt);
    }
    
    void Swap(int x,int type) {
        if (type==0) return;
        Splay(x);
        int y;
        if (type==-1) {
            y=t[x].c[0];
            if (!y) return;
            while (t[y].c[1]) y=t[y].c[1];
        }
        else {
            y=t[x].c[1];
            if (!y) return;
            while (t[y].c[0]) y=t[y].c[0];
        }
        swap(t[x].id,t[y].id);swap(rev[t[x].id],rev[t[y].id]);
    }
    
    void Top(int x) {
        Splay(x);
        if (!t[x].c[0]) return;
        int y=t[x].c[1];
        if (!y) {
            t[x].c[1]=t[x].c[0];t[x].c[0]=0;
            return;
        }
        while (t[y].c[0]) y=t[y].c[0];
        t[t[y].c[0]=t[x].c[0]].f=y;t[x].c[0]=0;
        Splay(y);
    }
    
    void Bottom(int x) {
        Splay(x);
        if (!t[x].c[1]) return;
        int y=t[x].c[0];
        if (!y) {
            t[x].c[0]=t[x].c[1];t[x].c[1]=0;
            return;
        }
        while (t[y].c[1]) y=t[y].c[1];
        t[t[y].c[1]=t[x].c[1]].f=y;t[x].c[1]=0;
        Splay(y);
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1,a;i<=n;i++) scanf("%d",&a),Add(a);
        for (int i=1;i<=m;i++) {
            char c[10];int x,y;
            scanf("%s%d",c+1,&x);
            if (c[1]=='T') Top(rev[x]);
            if (c[1]=='B') Bottom(rev[x]);
            if (c[1]=='I') {
                scanf("%d",&y);
                Swap(rev[x],y);
            }
            if (c[1]=='A') Splay(rev[x]),printf("%d
    ",t[t[rev[x]].c[0]].sz);
            if (c[1]=='Q') printf("%d
    ",t[Get_Kth(rt,x)].id);
        }
    }
    View Code
  • 相关阅读:
    Windows7旗舰版安装VS2008的SP1的问题(KB945140, KB947888)
    Hex RGB颜色值互换
    php沥遍目录结构
    linux ftp设置
    Android开发环境搭建
    php读取excel文件
    wordpress插件制作
    wordpress主题制作
    php读取excel文件(OLERead.php页代码)
    php ios推送
  • 原文地址:https://www.cnblogs.com/mastervan/p/11380837.html
Copyright © 2011-2022 走看看