zoukankan      html  css  js  c++  java
  • 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
    ",posnum(root,x));break;
                case 4:printf("%d
    ",posrank(root,x));break;
                case 5:ans=0;pospre(root,x);printf("%d
    ",ans);break;
                case 6:ans=0;possub(root,x);printf("%d
    ",ans);break;
            }
        }
        return 0;
    }

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

  • 相关阅读:
    【工具】模板引擎 Velocity
    【Android】Android 彩信发送的两种方式+源代码
    【Win7】 建立无线局域网实现共享上网
    【Android】java.net.SocketException: Permission denied解决
    Android中使用Post请求(网友版)
    Android通过post请求发送一个xml,解析返回xml数据
    学用MVC4做网站六后台管理:6.1管理员
    学用MVC4做网站六:后台管理
    html5的新增的标签和废除的标签
    HTML5新增的属性和废除的属性
  • 原文地址:https://www.cnblogs.com/2018zxy/p/9895281.html
Copyright © 2011-2022 走看看