1. 程式人生 > >非旋轉Treap:用時間換時間的有效手段

非旋轉Treap:用時間換時間的有效手段

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 80010
#define mp make_pair
using namespace std;
typedef pair<int,int> par;
int n,m,root;
int ls[N],rs[N],size[N],key[N],fa[N];
inline void pushup(int x)
{
    size[x]=size[ls[x]]+size[rs[x]]+1;
}
int merge(int x,int y)
{
    if(!x||!y) return x|y;
    if(key[x]>key[y])
    {
        rs[x]=merge(rs[x],y);fa[rs[x]]=x;
        pushup(x); return x;
    }
    ls[y]=merge(x,ls[y]);fa[ls[y]]=y;
    pushup(y); return y;
}
par split(int x,int k)
{
    if(!k) return mp(0,x);
    int lson=ls[x],rson=rs[x];
    if(k==size[lson])
    {
        ls[x]=0;pushup(x);
        fa[lson]=0;
        return mp(lson,x);
    }
    if(k==size[lson]+1)
    {
        rs[x]=0;pushup(x);
        fa[rson]=0;
        return mp(x,rson);
    }
    if(k<size[lson])
    {
        par t=split(lson,k);
        ls[x]=t.second;fa[ls[x]]=x;pushup(x);
        return mp(t.first,x);
    }
    par t=split(rson,k-size[ls[x]]-1);
    rs[x]=t.first;fa[rs[x]]=x;pushup(x);
    return mp(x,t.second);
}
int getid(int x)
{
    int flag=1,t=x,ans=0;
    while(t)
    {
        if(flag)ans+=size[ls[t]]+1;
        flag=(t==rs[fa[t]]);
        t=fa[t];
    }
    return ans-1;
}
int find(int x)
{
    x--;int t=root;
    while(1)
    {
        if(x==size[ls[t]]) return t;
        if(x<size[ls[t]]) t=ls[t];
        else x-=size[ls[t]]+1,t=rs[t];
    }
}
int main()
{
	cin >> n >> m ;
    for(int x,i=1;i<=n;i++)
    {
        scanf("%d",&x);
        size[x]=1,key[x]=rand()*rand();
        root=merge(root,x);
    }
    char flag[10];
    for(int x,y,i=1;i<=m;i++)
    {
        scanf("%s",flag);
        if(flag[0]=='T')
        {
            scanf("%d",&x);
            int id=getid(x);
            par t2=split(root,id+1),t1=split(t2.first,id);
            root=merge(t1.second,merge(t1.first,t2.second));
        }
        else if(flag[0]=='B')
        {
            scanf("%d",&x);
            int id=getid(x);
            par t2=split(root,id+1),t1=split(t2.first,id);
            root=merge(merge(t1.first,t2.second),t1.second);
        }
        else if(flag[0]=='I')
        {
            scanf("%d%d",&x,&y);
            if(!y)continue;
            if(y==-1)
            {
                int id=getid(x);
                par t3=split(root,id+1),t2=split(t3.first,id),t1=split(t2.first,id-1);
                root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second);
            }
            else
            {
                int id=getid(x);
                par t3=split(root,id+2),t2=split(t3.first,id+1),t1=split(t2.first,id);
                root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second);
            }
        }
        else if(flag[0]=='A')
        {
            scanf("%d",&x);
            printf("%d\n",getid(x));
        }
        else
        {
            scanf("%d",&x);
            printf("%d\n",find(x));
        }
    }
    return 0;
}