其实之前学过一次非旋转 treap,但是全忘光了,今天复习一下. 

洛谷 P3369 【模板】普通平衡树  

code: 

#include <bits/stdc++.h>
#define N  100006
#define lson t[x].ls
#define rson t[x].rs
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int root;
namespace treap
{
    int tot;
    struct node
    {
        int val,size,ls,rs,ran;
    }t[N];
    inline void newnode(int &x,int val)
    {
        ++tot;
        t[tot].size=1;
        t[tot].val=val;
        t[tot].ran=rand();
        t[tot].ls=t[tot].rs=0;
        x=tot;
    }
    inline void pushup(int x)
    {
        t[x].size=t[lson].size+t[rson].size+1;
    }
    void split(int x,int &l,int &r,int val)
    {
        if(!x) { l=r=0; return; }
        if(t[x].val<=val)  l=x, split(t[x].rs,t[l].rs,r,val);
        else   r=x, split(t[x].ls,l,t[r].ls,val);
        pushup(x);
    }
    void merge(int &x,int a,int b)
    {
        if(!a||!b)  { x=a+b;   return; }
        if(t[a].ran<t[b].ran)  x=a, merge(t[x].rs,t[a].rs,b);
        else  x=b, merge(t[x].ls,a,t[b].ls);
        pushup(x);
    }
    void insert(int val)
    {
        int x=0,y=0,z=0;
        newnode(z,val);
        split(root,x,y,val-1);
        merge(x,x,z);
        merge(root,x,y);
    }
    void del(int val)
    {
        int x=0,y=0,z=0;
        split(root,x,y,val);
        split(x,x,z,val-1);
        merge(z,t[z].ls,t[z].rs);
        merge(x,x,z);
        merge(root,x,y);
    }
    void ask_rank(int v)
    {
        int x=0,y=0;
        split(root,x,y,v-1);
        printf("%d\n",t[x].size+1);
        merge(root,x,y);
    }
    void ask_num(int x,int kth)
    {
        while(t[lson].size+1!=kth)
        {
            if(t[lson].size>=kth)  x=lson;
            else kth-=(t[lson].size+1),x=rson;
        }
        printf("%d\n",t[x].val);
    }
    void ask_front(int v)
    {
        int x=0,y=0;
        split(root,x,y,v-1);
        ask_num(x,t[x].size);
        merge(root,x,y);
    }
    void ask_back(int v)
    {
        int x=0,y=0;
        split(root,x,y,v),ask_num(y,1), merge(root,x,y);
    }
};
int main()
{
    // setIO("input");
    int i,j,n;
    srand(16);
    scanf("%d",&n);
    for(i=1;i<=n;++i)
    {
        int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1) treap::insert(x);
        if(opt==2) treap::del(x);
        if(opt==3) treap::ask_rank(x);
        if(opt==4) treap::ask_num(root,x);
        if(opt==5) treap::ask_front(x);
        if(opt==6) treap::ask_back(x);
    }
    return 0;
}

  

01-10 18:33