bzoj3224

学习了下treap

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int inf=1<<29;
int n,mn,root,delta,tot,ans;
int size[100010],child[100010][2],cnt[100010],key[100010],p[100010];
void update(int x)
{
    size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x];
}
void rotate(int&x,int t)
{
    int y=child[x][t];
    child[x][t]=child[y][1-t];
    child[y][1-t]=x;
    update(x);
    update(y);
    x=y;
}
void insert(int&x,int k)
{
    if(x)
    {
        if(key[x]==k) cnt[x]++;
        else
        {
            int t=key[x]<k;
            insert(child[x][t],k);
            if(p[x]<p[child[x][t]]) rotate(x,t);
        }
    }
    else
    {
        ++tot;
        x=tot;
        p[x]=rand();
//      printf("%d\n",p[x]); 
        key[x]=k;
        cnt[x]=1;
    }
    update(x);
}
void erase(int&x,int k)
{
    if(key[x]==k)
    {
        if(cnt[x]>1)
        {
            cnt[x]--;
            update(x);
            return;
        }
        if(!child[x][0]&&!child[x][1])
        {
            x=0;
            return;
        }
        int t=p[child[x][1]]>p[child[x][0]];
        rotate(x,t);
        erase(child[x][t^1],k);
    } else erase(child[x][key[x]<k],k);
    update(x);
}
int find(int x,int k)
{
    if(k<=size[child[x][0]])
        return find(child[x][0],k);
    k-=size[child[x][0]]+cnt[x];
    if(k<=0) return key[x];
    return find(child[x][1],k);
}
int findrank(int x,int k)
{
    if(key[x]==k) return size[child[x][0]]+1;
    if(key[x]<k) return findrank(child[x][1],k)+cnt[x]+size[child[x][0]];
    if(key[x]>k) return findrank(child[x][0],k);
}
void findpro(int x,int k)
{
    if(x==0) return;
    if(key[x]<k)
    {
        ans=key[x];
        findpro(child[x][1],k);
    } else findpro(child[x][0],k);
}
void findnxt(int x,int k)
{
    if(x==0) return;
    if(key[x]>k)
    {
        ans=key[x];
        findnxt(child[x][0],k);
    } else findnxt(child[x][1],k);
}
int main()
{
    p[0]=-inf;
    scanf("%d",&n);
    while(n--)
    {
        int opt,a; scanf("%d%d",&opt,&a);
//      printf("----------\nopt=%d\n",opt);
        if(opt==1) insert(root,a);
        if(opt==2) erase(root,a);
        if(opt==3) printf("%d\n",findrank(root,a));
        if(opt==4) printf("%d\n",find(root,a));
        if(opt==5) {findpro(root,a);printf("%d\n",ans);ans=0;}
        if(opt==6) {findnxt(root,a);printf("%d\n",ans);ans=0;}
//      printf("----------\n");
    }
    return 0;
}

 

posted @ 2016-11-26 13:13  19992147  阅读(167)  评论(0编辑  收藏  举报