题意

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

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

\(n \leq 10^5\)

分析

用范浩强Treap实现。具体原理:










范浩强对函数式编程在OI中的应用做了很好的引入工作。

非旋式Treap的精华在于那个merge。
merge的参数要求保证x中最大的数不大于y中最小的数。
这样在合并一个子树的时候,有两种等价情况,一种是x是y的左儿子,一种是y是x的右儿子。
选择的依据是priority,这样平衡的道理就跟普通Treap一样了。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=1e5+7;

int sz;
struct Treap
{
    int val[MAXN],pri[MAXN];
    int ch[MAXN][2],siz[MAXN];

    void pushup(int x)
    {
        siz[x]=siz[ch[x][0]]+1+siz[ch[x][1]];
    }

    int new_node(int v)
    {
        val[++sz]=v,
        pri[sz]=rand()<<15|rand();
        ch[sz][0]=ch[sz][1]=0,
        siz[sz]=1;
        return sz;
    }

    int merge(int x,int y)
    {
        if(!x||!y)
            return x+y;
        if(pri[x]<pri[y])
        {
            ch[x][1]=merge(ch[x][1],y);
            pushup(x);
            return x;
        }
        else
        {
            ch[y][0]=merge(x,ch[y][0]);
            pushup(y);
            return y;
        }
    }

    void split(int now,int v,int&x,int&y)
    {
        if(!now)
            x=y=0;
        else
        {
            if(val[now]<=v)
            {
                x=now,split(ch[now][1],v,ch[now][1],y);
            }
            else
            {
                y=now,split(ch[now][0],v,x,ch[now][0]);
            }
            pushup(now);
        }
    }

    void ins(int&now,int v)
    {
        int x,y;
        split(now,v,x,y);
        now=merge(merge(x,new_node(v)),y);
    }

    void del(int&now,int v)
    {
        int x,y,z;
        split(now,v,x,z);
        split(x,v-1,x,y);
        y=merge(ch[y][0],ch[y][1]);
        now=merge(merge(x,y),z);
    }

    int rank(int&now,int v)
    {
        int x,y;
        split(now,v-1,x,y);
        int ans=siz[x]+1;
        now=merge(x,y);
        return ans;
    }

    int kth(int now,int k)
    {
        while(1)
        {
            if(k<=siz[ch[now][0]])
                now=ch[now][0];
            else if(k==siz[ch[now][0]]+1)
                return now;
            else
                k-=siz[ch[now][0]]+1,now=ch[now][1];
        }
    }

    int pre(int&now,int v)
    {
        int x,y;
        split(now,v-1,x,y);
        int ans=kth(x,siz[x]);
        now=merge(x,y);
        return ans;
    }

    int suc(int&now,int v)
    {
        int x,y;
        split(now,v,x,y);
        int ans=kth(y,1);
        now=merge(x,y);
        return ans;
    }
}T;

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    srand(20030506);
    int root=0;
    int n;
    read(n);
    while(n--)
    {
        static int opt,x;
        read(opt);read(x);
        if(opt==1) // insert
        {
            T.ins(root,x);
        }
        else if(opt==2) // delete
        {
            T.del(root,x);
        }
        else if(opt==3) // rank
        {
            printf("%d\n",T.rank(root,x));
        }
        else if(opt==4) // kth
        {
            printf("%d\n",T.val[T.kth(root,x)]);
        }
        else if(opt==5) // precursor
        {
            printf("%d\n",T.val[T.pre(root,x)]);
        }
        else // successor
        {
            printf("%d\n",T.val[T.suc(root,x)]);
        }
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

LG3369 【模板】普通平衡树的更多相关文章

  1. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  2. luoguP3369[模板]普通平衡树(Treap/SBT) 题解

    链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...

  3. 【洛谷P3369】 (模板)普通平衡树

    https://www.luogu.org/problemnew/show/P3369 Splay模板 #include<iostream> #include<cstdio> ...

  4. [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)

    解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...

  5. 【模板】平衡树——Treap和Splay

    二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...

  6. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  7. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  8. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  9. 文艺平衡Splay树学习笔记(2)

    本blog会讲一些简单的Splay的应用,包括但不局限于 1. Splay 维护数组下标,支持区间reserve操作,解决区间问题 2. Splay 的启发式合并(按元素多少合并) 3. 线段树+Sp ...

  10. [note]fhq_treap

    fhq_treap 这东西据说是某个叫范浩强的神仙搞出来的, 他的这种treap可以不用旋转并且资磁很多平衡树操作, 复杂度通过随机的键值来保证(树大致平衡,期望一次操作复杂度\(logn\)) 依靠 ...

随机推荐

  1. SpringBoot中的数据库连接池

    内置的连接池 目前Spring Boot中默认支持的连接池有dbcp,dbcp2, tomcat, hikari三种连接池. 数据库连接可以使用DataSource池进行自动配置. 由于Tomcat数 ...

  2. 使用MyBatis Generator自动生成实体、mapper和dao层

    原文链接 通过MyBatis Generator可以自动生成实体.mapper和dao层,记录一下怎么用的. 主要步骤: 关于mybatis从数据库反向生成实体.DAO.mapper: 参考文章:ht ...

  3. Freemarker 简介

    1.动态网页和静态网页差异 在进入主题之前我先介绍一下什么是动态网页,动态网页是指跟静态网页相对应的一种网页编程技术.静态网页,随着HTML代码的生成,页面的内容和显示效果就不会再发生变化(除非你修改 ...

  4. 20170728xlVba简单的匹配

    Sub MatchData() Dim i As Long, EndRow As Long, Key As String Dim Rng As Range Dim Dic As Object Set ...

  5. 20170706wdVBA正则表达式提取题目

    Public Sub GetContents() Dim Reg As Object Dim Matches As Object Dim OneMatch As Object Dim Index As ...

  6. pyspark使用ipython

    在Ubuntu下,安装ipython很简单: $sudo apt-get install ipython 在bash env中添加变量: export IPYTHON=1 export IPYTHON ...

  7. XML——Schema

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  8. C++ primer 第四版 练习3.13,3.14

    读一组整数到 vector 对象,计算并输出每对相邻元素的 和.如果读入元素个数为奇数,则提示用户后一个元素 没有求和,并输出其值. vector<int> ivec; int ival; ...

  9. MyEclipse WebSphere开发教程:WebSphere 7安装指南(二)

    [周年庆]MyEclipse个人授权 折扣低至冰点!立即开抢>> [MyEclipse最新版下载] 三.禁用Windows系统服务 默认情况下,当安装WebSphere Applicati ...

  10. 高并发下linux ulimit优化

    系统性能一直是一个受关注的话题,如何通过最简单的设置来实现最有效的性能调优,如何在有限资源的条件下保证程序的运作,ulimit 是我们在处理这些问题时,经常使用的一种简单手段.ulimit 是一种 l ...