题目描述

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

  1. 插入x数

  2. 删除x数(若有多个相同的数,因只删除一个)

  3. 查询x数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)

  4. 查询排名为x的数

  5. 求x的前驱(前驱定义为小于x,且最大的数)

  6. 求x的后继(后继定义为大于x,且最小的数)

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1: 复制

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
输出样例#1: 复制

106465
84185
492737

说明

时空限制:1000ms,128M

1.n的数据范围: n \leq 100000n≤100000

2.每个数的数据范围: [-{10}^7, {10}^7][−107,107]

来源:Tyvj1728 原名:普通平衡树

在此鸣谢

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; const int N = 1e5+;
const int INF = ; int n, opt, x;
struct NODE
{
NODE *fa;
NODE *son[];
int siz;
int num, cnt;
}node[N]; typedef NODE* Tree;
Tree Root, now_node, null; inline void init()
{
Root = now_node = null = node;
null->son[] = null->son[] = null;
} inline int read()
{
char c = getchar(); int num = , f = ;
for(; !isdigit(c); c = getchar())
f = c == '-' ? - : f;
for(; isdigit(c); c = getchar())
num = num * + c - '';
return num * f;
} inline Tree new_node(int num, Tree fa)
{
++ now_node;
now_node->siz = ;
now_node->num = num;
now_node->fa = fa;
now_node->son[] = now_node->son[] = null;
return now_node;
} inline bool getgx(Tree root)
{
return root->fa->son[] == root;
} inline void connect(Tree root, Tree fa, bool flag)
{
if(fa != null)
fa->son[flag] = root;
else
Root = root;
root->fa = fa;
} inline void update(Tree root)
{
root->siz = root->son[]->siz + root->son[]->siz + root->cnt;
} inline void rotate(Tree root)
{
Tree fa = root->fa;
bool a = getgx(root), b = !a;
connect(root->son[b], fa, a);
connect(root, fa -> fa, getgx(fa));
connect(fa, root, b);
update(fa);
update(root);
if(root->fa == null)
Root = root;
} inline void splay(Tree root, Tree goal)
{
for(; root->fa != goal; rotate(root))
if(root->fa->fa != goal)
rotate(getgx(root) == getgx(root->fa) ? root->fa : root);
} void insert(int num)
{
if(Root == null)
{
Root = new_node(num, null);
Root->cnt = ;
}
else
{
Tree root = Root;
for(; root->num != num; root = root->son[num > root->num])
{
++ (root->siz);
if(root->son[num > root->num] == null)
root->son[num > root->num] = new_node(num, root);
}
++ (root->cnt);
splay(root, null);
}
} void erase(int num)
{
if(Root == null)
return;
else
{
Tree root = Root;
for(;root != null && root->num != num; root = root->son[num > root->num]);
if(root == null)
return;
splay(root, null);
-- (root->cnt);
if(!root->cnt)
{
if(root->son[] != null)
{
Tree tmp = root->son[];
for(;tmp->son[] != null; tmp = tmp->son[]);
splay(tmp, null);
Root->son[] = root->son[];
if(Root->son[] != null)
Root->son[]->fa = Root;
}
else
{
Root = root->son[];
Root->fa = null;
}
}
}
} inline int query_rank(int num)
{
int rank = ;
for(Tree root = Root; root != null; root = root->son[num > root->num])
{
if(num == root->num)
return rank + root->son[]->siz + ;
if(num > root->num)
rank += root->son[]->siz + root->cnt;
}
return rank;
} inline int query_num(int rank)
{
for(Tree root = Root; root != null; )
{
if(rank <= root->son[]->siz)
root = root->son[];
else if(rank > root->son[]->siz + root->cnt)
rank -= root->son[]->siz + root->cnt, root = root->son[];
else
return root->num;
}
} inline int query_pre(int x)
{
int pre = -INF;
for(Tree root = Root; root != null; root = root->son[x > root->num])
{
if(x > root->num)
pre = max(pre, root->num);
}
return pre;
} inline int query_nxt(int x)
{
int nxt = INF;
for(Tree root = Root; root != null; root = root->son[x >= root->num])
{
if(root->num > x)
nxt = min(nxt, root->num);
}
return nxt;
} int main()
{
init();
n = read();
for(int i = ; i <= n; ++ i)
{
opt = read(), x = read();
switch(opt)
{
case :
insert(x); break;
case :
erase(x); break;
case :
printf("%d\n", query_rank(x)); break;
case :
printf("%d\n", query_num(x)); break;
case :
printf("%d\n", query_pre(x)); break;
default:
printf("%d\n", query_nxt(x));
}
}
return ;
}

Splay P3369 【模板】普通平衡树(Treap/SBT)的更多相关文章

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

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

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

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

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

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...

  4. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  5. [luogu P3369]【模板】普通平衡树(Treap/SBT)

    [luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...

  6. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

  7. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  8. 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...

  9. P3369 【模板】普通平衡树 Treap

    P3369 [模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询 ...

  10. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

随机推荐

  1. Comet OJ Contest 4

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  2. Redis缓存如何保证一致性

    为什么使用Redis做缓存 MySQL缺点 单机连接数目有限 对数据进行写速度慢 Redis优点 内存操作数据速度快 IO复用,速度快 单线程模型,避免线程切换带来的开销,速度快 一致性问题 读数据的 ...

  3. Ipython 和 python 的区别

    IPython是一个python交互shell,它比默认的python shell更易于使用.它支持自动变量完成.自动缩进.bash shell命令,并且内置了许多有用的函数和函数. IPython是 ...

  4. ORA-00001:unique constraint violated解决

    转自:https://www.2cto.com/database/201211/172340.html ORA-00001:unique constraint violated解决 今天往数据库中插入 ...

  5. lumen中安装及使用redis作为cache

      1.安装redis模块在compose.json的require中添加 "predis/predis": "*","illuminate/redi ...

  6. django2以后的版本Foreignkey的变动

    目录 class User(AbstractUser): """用户表""" job = models.ManyToManyField(to ...

  7. 【TestNG】使用代码方式调用TestNG用例执行

    TestNG的用例除了直接运行之外,还可以使用代码来调用,这样做的好处在于我们可以将其嵌入其他代码中,来执行这些TestNG用例,方法如下: 1.直接调用用例类 范例:定义了两个测试用例类为Depen ...

  8. Linux命令——su 、su -、sudo

    前言 大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户. 切换用户身份有两个命令 su [-] usernam ...

  9. Linux学习之四-Linux发行版及版本比较

    Linux发行版及版本比较 三大家族: Fedora是基于RHEL,CentOS,Scientific Linux, 和Oracle Linux的社区版本.相比RHEL,Fedora打包了显著的更多的 ...

  10. 从Retrofit的源码来看 HTTP

    关于Retrofit是啥,这里就不多解释了,还是先来瞅下官网: 而这次主要是了解它的底层动作机制,而在了解底层之前先来回顾一下官网的整体使用步骤: 咱们也以官网的这个例子为例,先从简单的使用开始逐步深 ...