SBT模版

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3378  Solved: 1379
[Submit][Status][Discuss]

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的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

Source

平衡树

#include<cstdio>
#include<cstring>
#define N 2001000
using namespace std;
struct SBT
{
    int key,cnt;
    int l,r,size,sc;
}s[N];
int root,n,m;
void left_rotate(int &x)
{
    int y=s[x].r;
    s[x].r=s[y].l;
    s[y].l=x;
    s[y].size=s[x].size;
    s[y].sc=s[x].sc;
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    x=y;
}
void right_rotate(int &x)
{
    int y=s[x].l;
    s[x].l=s[y].r;
    s[y].r=x;
    s[y].size=s[x].size;
    s[y].sc=s[x].sc;
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    x=y;
}
void keep(int &x,int flag)
{
    s[x].size=s[s[x].l].size+s[s[x].r].size+1;
    s[x].sc=s[s[x].l].sc+s[s[x].r].sc+s[x].cnt;
    if(!flag)
    {
        if(s[s[s[x].l].l].size>s[s[x].r].size)right_rotate(x);
        else if(s[s[s[x].l].r].size>s[s[x].r].size)left_rotate(s[x].l),right_rotate(x);
        else return ;
    }
    else
    {
        if(s[s[s[x].r].r].size>s[s[x].l].size)left_rotate(x);
        else if(s[s[s[x].r].l].size>s[s[x].l].size)right_rotate(s[x].r),left_rotate(x);
        else return ;
    }
    keep(s[x].l,0);
    keep(s[x].r,1);
    keep(x,0);
    keep(x,1);
}
void insert(int &x,int key)
{
    if(!x)
    {
        x=++n;
        s[x].size=s[x].sc=s[x].cnt=1;
        s[x].key=key;
    }
    else
    {
        if(key==s[x].key)s[x].cnt++,s[x].sc++;
        else if(key<s[x].key)insert(s[x].l,key),keep(x,0);
        else insert(s[x].r,key),keep(x,1);
    }

}
void del(int &x,int key)
{
    if(s[x].key==key)
    {
        if(s[x].cnt>1)s[x].cnt--,s[x].sc--;
        else if(!s[x].l&&!s[x].r)x=0;
        else if(!s[x].l*s[x].r)x=s[x].l+s[x].r;
        else if(s[s[x].l].size>s[s[x].r].size)right_rotate(x),del(s[x].r,key),keep(x,0);
        else left_rotate(x),del(s[x].l,key),keep(x,1);
    }
    else if(key<s[x].key)del(s[x].l,key),keep(x,1);
    else del(s[x].r,key),keep(x,0);
}
int find(int &x,int k)
{
    if(s[s[x].l].sc<k&&k<=s[s[x].l].sc+s[x].cnt)return s[x].key;
    if(k<=s[s[x].l].sc)return find(s[x].l,k);
    else return find(s[x].r,k-s[s[x].l].sc-s[x].cnt);
}
int rank(int &x,int key)
{
    if(s[x].key==key)return s[s[x].l].sc+1;
    if(key<s[x].key)return rank(s[x].l,key);
    else return rank(s[x].r,key)+s[x].cnt+s[s[x].l].sc;
}
int getmin()
{
    int x=root;
    for(;s[x].l;x=s[x].l);
    return s[x].key;
}
int getmax()
{
    int x=root;
    for(;s[x].r;x=s[x].r);
    return s[x].key;
}
int pred(int &x,int y,int key)
{
    if(!x)return y;
    if(key<=s[x].key)return pred(s[x].l,y,key);
    else return pred(s[x].r,x,key);
}
int succ(int &x,int y,int key)
{
    if(!x)return y;
    if(key<s[x].key)return succ(s[x].l,x,key);
    else return succ(s[x].r,y,key);
}
int main()
{
    int i,t,x;
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&t,&x);
        switch(t)
        {
            case 1:insert(root,x);break;
            case 2:del(root,x);break;
            case 3:printf("%d\n",rank(root,x));break;
            case 4:printf("%d\n",find(root,x));break;
            case 5:printf("%d\n",s[pred(root,0,x)].key);break;
            case 6:printf("%d\n",s[succ(root,0,x)].key);break;
        }
    }
    return 0;
}

  

时间: 2024-08-06 17:09:24

SBT模版的相关文章

平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】

平衡树初阶——AVL平衡二叉查找树 一.什么是二叉树 1. 什么是树. 计算机科学里面的树本质是一个树状图.树首先是一个有向无环图,由根节点指向子结点.但是不严格的说,我们也研究无向树.所谓无向树就是将有向树的所有边看成无向边形成的树状图.树是一种递归的数据结构,所以我们研究树也是按照递归的方式去研究的. 2.什么是二叉树. 我们给出二叉树的递归定义如下: (1)空树是一个二叉树. (2)单个节点是一个二叉树. (3)如果一棵树中,以它的左右子节点为根形成的子树都是二叉树,那么这棵树本身也是二叉

C++ 类模板三(类模版中的static关键字)

//类模版中的static关键字 #include<iostream> using namespace std; /* 类模板本质上是c++编译器根据类型参数创建了不同的类, c++编译器在利用类模板生成类的时候会为每个类生成一个static变量 那么对于类中的static关键字就非常好理解了 static关键字修饰的变量是属于类的 同一个类的对象共享类的static静态变量 类模板中的static修饰的变量数据类型必须是确定的 不可以是类型参数 因为静态变量在类对象之前初始化 这时候还没有通

SBT详解

文章转载自http://beike.iteye.com/blog/1575296 SBT = (not so) Simple Build Tool,是scala的构建工具,与java的maven地位相同.其设计宗旨是让简单的项目可以简单的配置,而复杂的项目可以复杂的配置... https://github.com/notyy/sbtTemplate 是我配置好的一个sbt项目,已经配置好了单元测试框架specs2,log引擎logback,slf4j,和eclipse项目生成插件sbteclip

zabbix导入模版问题解决办法

当我们监控一些东西需要使用zabbix模版的时候,而模版没有怎么办?最简单的方法就是导入模版了 模版可以去https://www.zabbix.org/wiki/Zabbix_Templates/Official_Templates这里下载 而在导入的时候会报一些错误,下面给出导入vmware template报错的解决办法: 首先检查zabbix中是不是有模版对应的value map,没有的话导入的时候就报错啦. 手工创建value map: zabbix:在Administrator->ge

NAT配置模版

A 类:10.0.0.0-10.255.255.255 B 类:172.16.0.0-172.31.255.255 C 类:192.168.0.0-192.168.255.255 上述三个范围内的地址不会在因特网上被分配,因此可以不必向ISP 或注册中心申请而在公司或企业内部自由使用. NAT实现方式:静态转换.动态转换.端口多路复用 1.静态转换: 第一步,设置外部端口 interface serial 0/0 ip address 与ISP互联的地址 ip nat outside 第二步,设

主动给用户发消息-微信公众号模版消息

微信公众号模版消息最大的作用就是用户在平台上提交订单或发生其它行为时,平台可以给用户发送简要的交易信息,且公众平台主动给用户发送消息目前最多的就是1.模版消息:2.客服消息. 公众号配置 首先申请一个需要的模版消息   其次,发送模版消息必须要用户的openid,获取教程可参考之前的获取用户信息篇 后台代码 我的模版消息是用来提醒交易状态的,故以网站中以交易业务流程为例 万能调用 //微信通知 $id = get_order_id($out_trade_no);//获取订单的ID $uid =

QBC查询、离线条件查询(DetachedCriteric)和分页查询模版

一.QBC检索步骤 QBC检索步骤: 1.调用Session的createCriteria()方法创建一个Criteria对象. 2.设定查询条件.Expression类提供了一系列用于设定查询条件的静态方法, 这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件. Criteria的add()方法用于加入查询条件. 3.调用Criteria的list()方法执行查询语句.该方法返回List类型的查询结果,在 List集合中存放了符合查询条件的持久化对象. 比较运

数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline __attri\ bute__( ( optimize( "-O2" ) ) ) Inline void read (int &now) { now = 0; register char word = getchar (); bool temp = false; while (wor

【设计模式】模版方法模式

1.定义 1.1 标准定义 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.TemplateMethod lets subclasses redefine certain steps of an algorithm without changing the algorithm'sstructure.( 定义一个操作中的算法的框架, 而将一些步骤延迟到子类中. 使得子类可以