Treap树

 

Description

这是一道模板题。

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

  1. 插入 x  数;
  2. 删除 x数(若有多个相同的数,因只删除一个);
  3. 查询 x  数的排名(若有多个相同的数,因输出最小的排名);
  4. 查询排名为 x 的数;
  5. 求 x  的前趋(前趋定义为小于 x ,且最大的数);
  6. 求 x  的后继(后继定义为大于 x,且最小的数)。

Input

第一行为 n ,表示操作的个数,下面 n 行每行有两个数 opt 和 x,opt 表示操作的序号(1≤opt≤6)。

Output

对于操作 3、4、5、6 每行输出一个数,表示对应答案。

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 



1≤n≤105,−107≤x≤10

 

思路:Treap模板

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
const int maxn = 100007;
int i,j,k,l,ans,num,root,x,op,n;
int size[maxn],key[maxn],sum[maxn],sam[maxn];
int t[maxn][2];
void update(int x)
{
    size[x]=size[t[x][0]]+size[t[x][1]]+sam[x];
}
void rotate(int &x,int z)
{
    int y=t[x][z];
    t[x][z]=t[y][1-z];
    t[y][1-z]=x;
    update(x);update(y);
    x=y;
}
void insert(int &x,int y)
{
    if(!x)
    {
        x=++num;size[x]=1;sam[x]=1;key[x]=rand();sum[x]=y;
        return ;
    }
    size[x]++;
    if(sum[x]==y) sam[x]++;
    else if(y>sum[x])
    {
        insert(t[x][1],y);
        if(key[t[x][1]]<key[x]) rotate(x,1);
    }
    else
    {
        insert(t[x][0],y);
        if(key[t[x][0]]>key[x]) rotate(x,0);
    }
}
void del(int &x,int y)
{
    if(!x) return ;
    if(sum[x]==y)
    {
        if(sam[x]>1)
        {
            size[x]--,sam[x]--;return ;
        }
        else if(t[x][0]*t[x][1]==0) x=t[x][0]+t[x][1];
        else
        {
            if(key[t[x][0]]<key[t[x][1]]) rotate(x,0),del(x,y);
            else rotate(x,1),del(x,y);
        }
    }
    else if(y>sum[x]) size[x]--,del(t[x][1],y);
    else size[x]--,del(t[x][0],y);
}
int posnum(int x,int y)
{
    if(!x) return 0;
    if(sum[x]==y) return size[t[x][0]]+1;
    else if(sum[x]<y) return posnum(t[x][1],y)+sam[x]+size[t[x][1]];
    else return posnum(t[x][0],y);
}
int posrank(int x,int y)
{
    if(!x) return 0;
    if(size[t[x][0]]>=y) return posrank(t[x][0],y);
    else if(size[t[x][0]]+sam[x]<y) return posrank(t[x][1],y-size[t[x][0]]-sam[x]);
    else return sum[x];
}
void pospre(int x,int y)
{
    if(!x) return ;
    if(sum[x]<y) ans=sum[x],pospre(t[x][1],y);
    else pospre(t[x][0],y);
}
void possub(int x,int y)
{
    if(!x) return ;
    if(sum[x]>y) ans=sum[x],possub(t[x][0],y);
    else possub(t[x][1],y);
}
int main(void)
{
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&op,&x);
        switch(op)
        {
            case 1:insert(root,x);break;
            case 2:del(root,x);break;
            case 3:printf("%d\n",posnum(root,x));break;
            case 4:printf("%d\n",posrank(root,x));break;
            case 5:ans=0;pospre(root,x);printf("%d\n",ans);break;
            case 6:ans=0;possub(root,x);printf("%d\n",ans);break;
        }
    }
    return 0;
}

参考文章:https://blog.csdn.net/doyouseeman/article/details/52049675

posted @ 2018-11-02 11:26  麟阁  阅读(96)  评论(0编辑  收藏  举报