FHQ Treap学习

安利一下blog,看一下:https://www.luogu.org/blog/Chanis/fhq-treap

code:

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<cmath>
const int maxn=500006;
int n,m,q,x,y,z,cnt;
int size[maxn],ch[maxn][3],val[maxn],rnd[maxn],root;
inline int creat(int k)
{
    size[++cnt]=1;
    val[cnt]=k;
    rnd[cnt]=rand();
    return cnt;
}
inline void update(int s)
{
    size[s]=size[ch[s][0]]+size[ch[s][1]]+1;
}
inline void split(int now,int &x,int &y,int k)
{
    if (!now) 
    {
        x=y=0;
        return;
    }
    if (val[now]<=k)
    {
        x=now,split(ch[now][1],ch[now][1],y,k);
    }
    else 
    {
        y=now,split(ch[now][0],x,ch[now][0],k);
    }
    update(now);
} 
inline int merge(int a,int b)
{
    if (!a||!b) return a+b;
    if (rnd[a]<rnd[b])
    {
        ch[a][1]=merge(ch[a][1],b);
        update(a);
        return a;
    }
    else 
    {
        ch[b][0]=merge(a,ch[b][0]);
        update(b);
        return b;
    }
}
inline void insert(int k)
{
    int cur=creat(k);
    split(root,x,y,k);
    root=merge(merge(x,cur),y);
}
inline void del(int k)
{
        split(root,x,z,k);
        split(x,x,y,k-1);
        y=merge(ch[y][0],ch[y][1]);
        root=merge(merge(x,y),z);//记得要先merge起x,y 
}
inline int find_k(int s,int k)
{
    for (;;)
    {
        if (size[ch[s][0]]>=k) s=ch[s][0]; //(注意是比较儿子的size,因为可能有一样的数)
        else if (k==size[ch[s][0]]+1) return s;
        else
        {
            k-=size[ch[s][0]]+1;
            s=ch[s][1]; 
        } 
    }
}
inline int pre(int s,int k)
{
    split(s,x,y,k-1);
    int tmp=val[find_k(x,size[x])];
    root=merge(x,y);
    return tmp;
}
inline int nxt(int s,int k)
{
    split(s,x,y,k);
    int tmp=val[find_k(y,1)];
    root=merge(x,y);
    return tmp;
}
inline void cout(int k) 
{
    printf("%d\n",k);
}
int main()
{
    srand((unsigned)(time(NULL)));
    std::cin>>m;
    for (int i=1,q1,q2;i<=m;++i)
    {
        scanf("%d%d",&q1,&q2);
        if (q1==1) 
        {
            int cur=creat(q2);
            split(root,x,y,q2);
            root=merge(merge(x,cur),y);
        }
        if (q1==2) 
        {
            split(root,x,z,q2);
            split(x,x,y,q2-1);
            y=merge(ch[y][0],ch[y][1]);
            root=merge(merge(x,y),z);
//            del(q2);
        }
        if (q1==3) 
        {
            split(root,x,y,q2-1);
            cout(size[x]+1);
            root=merge(x,y);
        }
        if (q1==4) cout(val[find_k(root,q2)]);
        if (q1==5) cout(pre(root,q2));
        if (q1==6) cout(nxt(root,q2));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/bullshit/p/9587926.html