AC日记——模板普通平衡树(Treap/SBT) 洛谷 P3369

Posted Only U - IU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC日记——模板普通平衡树(Treap/SBT) 洛谷 P3369相关的知识,希望对你有一定的参考价值。

【模板】普通平衡树(Treap/SBT)

 

思路:

  劳资敲了一个多星期;

  劳资终于a了;

  劳资一直不a是因为一个小错误;

  劳资最后看的模板;

  劳资现在很愤怒;

  劳资不想谈思路!!!

 

来,上代码:

#include <cstdio>

using namespace std;

#define maxn 1000005

struct SplayTreeNodeType {
    int w,key,opi,size,ch[2];
};
struct SplayTreeNodeType tree[maxn];

int n,root,tot;

inline void updata(int now)
{
    tree[now].size=tree[now].w;
    if(tree[now].ch[0]) tree[now].size+=tree[tree[now].ch[0]].size;
    if(tree[now].ch[1]) tree[now].size+=tree[tree[now].ch[1]].size;
}

inline int pre()
{
    int now=tree[root].ch[0];
    while(tree[now].ch[1]) now=tree[now].ch[1];
    return now;
}

inline int suc()
{
    int now=tree[root].ch[1];
    while(tree[now].ch[0]) now=tree[now].ch[0];
    return now;
}

inline int getson(int now)
{
    return tree[tree[now].opi].ch[1]==now;
}

void rotate(int now)
{
    int opi=tree[now].opi,fopi=tree[opi].opi,pos=getson(now);
    tree[opi].ch[pos]=tree[now].ch[pos^1];
    tree[tree[opi].ch[pos]].opi=opi;
    tree[now].ch[pos^1]=opi;tree[opi].opi=now;
    tree[now].opi=fopi;
    if(fopi) tree[fopi].ch[tree[fopi].ch[1]==opi]=now;
    updata(opi),updata(now);
}

void splay(int now)
{
    for(int opi;opi=tree[now].opi;rotate(now))
    {
        if(tree[opi].opi) rotate(getson(now)==getson(opi)?opi:now);
    }
    root=now;
}

int rank(int x)
{
    int now=root,ans=0;
    while(1)
    {
        if(x<tree[now].key) now=tree[now].ch[0];
        else
        {
            ans+=tree[now].ch[0]?tree[tree[now].ch[0]].size:0;
            if(x==tree[now].key)
            {
                splay(now);
                return ans+1;
            }
            ans+=tree[now].w;
            now=tree[now].ch[1];
        }
    }
}

int rank_(int x)
{
    int now=root;
    while(1)
    {
        if(tree[now].ch[0]&&x<=tree[tree[now].ch[0]].size) now=tree[now].ch[0];
        else
        {
            int tmp=(tree[now].ch[0]?tree[tree[now].ch[0]].size:0)+tree[now].w;
            if(x<=tmp) return tree[now].key;
            x-=tmp;now=tree[now].ch[1];
        }
    }
}

inline void clear(int now)
{
    tree[now].ch[0]=tree[now].ch[1]=tree[now].w=tree[now].size=tree[now].key=tree[now].opi=0;
}

inline void create(int x)
{
    tree[++tot].key=x;
    tree[tot].w=tree[tot].size=1;
    tree[tot].ch[0]=tree[tot].ch[1]=tree[tot].opi=0;
}

void insert(int x)
{
    if(!root) create(x),root=tot;
    else
    {
        int now=root,opi=0;
        while(1)
        {
            if(tree[now].key==x)
            {
                tree[now].w++;
                tree[now].size++;
                splay(now);
                break;
            }
            opi=now;
            now=tree[now].ch[x>tree[opi].key];
            if(!now)
            {
                create(x);
                tree[tot].opi=opi;
                tree[opi].ch[x>tree[opi].key]=tot;
                splay(tot);
                break;
            }
        }
    }
}

void del(int x)
{
    int t=rank(x);
    if(tree[root].w>1)
    {
        tree[root].w--;
        tree[root].size--;
        return ;
    }
    if(!tree[root].ch[0]&&!tree[root].ch[1])
    {
        clear(root);
        root=0;
        return ;
    }
    if(!tree[root].ch[0])
    {
        int tmp=root;
        root=tree[root].ch[1];
        tree[root].opi=0;
        clear(tmp);
        return ;
    }
    if(!tree[root].ch[1])
    {
        int tmp=root;
        root=tree[root].ch[0];
        tree[root].opi=0;
        clear(tmp);
        return ;
    }
    int pre1=pre(),tmp=root;
    splay(pre1);
    tree[root].ch[1]=tree[tmp].ch[1];
    tree[tree[tmp].ch[1]].opi=root;
    clear(tmp);updata(root);
}

inline void in(int &now)
{
    register int if_z=1;now=0;
    register char Cget=getchar();
    while(Cget>9||Cget<0)
    {
        if(Cget==-) if_z=-1;
        Cget=getchar();
    }
    while(Cget>=0&&Cget<=9)
    {
        now=now*10+Cget-0;
        Cget=getchar();
    }
    now*=if_z;
}

int main()
{
    in(n);int ty,x;
    while(n--)
    {
        in(ty),in(x);
        if(ty==1) insert(x);
        if(ty==2) del(x);
        if(ty==3) printf("%d\n",rank(x));
        if(ty==4) printf("%d\n",rank_(x));
        if(ty==5) insert(x),printf("%d\n",tree[pre()].key),del(x);
        if(ty==6) insert(x),printf("%d\n",tree[suc()].key),del(x);
    }
    return 0;
}

 

以上是关于AC日记——模板普通平衡树(Treap/SBT) 洛谷 P3369的主要内容,如果未能解决你的问题,请参考以下文章

luoguP3369[模板]普通平衡树(Treap/SBT) 题解

红黑树 ------ luogu P3369 模板普通平衡树(Treap/SBT)

替罪羊树 ------ luogu P3369 模板普通平衡树(Treap/SBT)

fhq treap ------ luogu P3369 模板普通平衡树(Treap/SBT)

数组splay ------ luogu P3369 模板普通平衡树(Treap/SBT)

[luogu P3369]模板普通平衡树(Treap/SBT)