P3369 【模板】普通平衡树(Treap/SBT)

题目描述

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

  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 原名:普通平衡树

在此鸣谢

code

treap 真是个好东西。。

 #include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std; const int N = ; struct Data{
int l,r,val,key,siz,cnt;
}t[N];
int Root,tn,ans; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF :*p1++;
}
inline int read() {
int x = ,f = ;char ch=nc();
for (; ch<''||ch>''; ch = nc())
if (ch == '-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
} inline void pushup(int x) {
t[x].siz = t[t[x].l].siz + t[t[x].r].siz + t[x].cnt;
}
inline void leftturn(int &k) {
int a = t[k].r;
t[k].r = t[a].l;
t[a].l = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
inline void rightturn(int &k) {
int a = t[k].l;
t[k].l = t[a].r;
t[a].r = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
void Insert(int &k,int x) {
if (k==) {
tn++;k = tn;
t[k].siz = t[k].cnt = ;
t[k].val = x;t[k].key = rand();
return ;
}
t[k].siz++;
if (t[k].val==x) t[k].cnt ++;
else if (x > t[k].val) {
Insert(t[k].r,x);
if (t[t[k].r].key < t[k].key) leftturn(k);
}
else {
Insert(t[k].l,x);
if (t[t[k].l].key < t[k].key) rightturn(k);
}
}
void Delete(int &k,int x) {
if (k==) return ;
if (t[k].val==x) {
if (t[k].cnt > ) {
t[k].cnt--;t[k].siz--;return ;
}
if (t[k].l * t[k].r == ) k = t[k].l + t[k].r;
else if (t[t[k].l].key < t[t[k].r].key) {
rightturn(k);Delete(k,x);
}
else {
leftturn(k);Delete(k,x);
}
}
else if (x > t[k].val) {
t[k].siz--;Delete(t[k].r,x);
}
else {
t[k].siz--;Delete(t[k].l,x);
}
}
int getk(int k,int x) {
if (k==) return ;
if (t[k].val==x) return t[t[k].l].siz + ;
else if (x > t[k].val)
return t[t[k].l].siz + t[k].cnt + getk(t[k].r,x);
else return getk(t[k].l,x);
}
int getkth(int k,int x) {
if (k==) return ;
if (x <= t[t[k].l].siz) return getkth(t[k].l,x);
else if (x > t[t[k].l].siz + t[k].cnt)
return getkth(t[k].r,x-t[t[k].l].siz-t[k].cnt);
else return t[k].val;
}
void getpre(int k,int x) {
if (k==) return ;
if (t[k].val < x) ans = k,getpre(t[k].r,x);
else getpre(t[k].l,x);
}
void getsuc(int k,int x) {
if (k==) return ;
if (t[k].val > x) ans = k,getsuc(t[k].l,x);
else getsuc(t[k].r,x);
} int main() {
int n = read();
while (n--){
int opt = read(),x = read();
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,x);
else if (opt==) printf("%d\n",getk(Root,x));
else if (opt==) printf("%d\n",getkth(Root,x));
else if (opt==) ans = ,getpre(Root,x),printf("%d\n",t[ans].val);
else ans = ,getsuc(Root,x),printf("%d\n",t[ans].val);
}
return ;
}

更新后的treap

 #include<cstdio>
#include<algorithm>
#include<ctime> using namespace std; #define lson t[k].l
#define rson t[k].r
const int N = ; struct Data{
int l,r,val,key,siz,cnt;
}t[N];
int Root,tn,ans; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF :*p1++;
}
inline int read() {
int x = ,f = ;char ch=nc();
for (; ch<''||ch>''; ch = nc())
if (ch == '-') f = -;
for (; ch>=''&&ch<=''; ch = nc())
x = x*+ch-'';
return x * f;
} inline void pushup(int k) {
t[k].siz = t[lson].siz + t[rson].siz + t[k].cnt;
}
inline void leftturn(int &k) {
int a = rson;
rson = t[a].l;
t[a].l = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
inline void rightturn(int &k) {
int a = lson;
lson = t[a].r;
t[a].r = k;
t[a].siz = t[k].siz;
pushup(k);
k = a;
}
void Insert(int &k,int x) {
if (k==) {
tn++;k = tn;
t[k].siz = t[k].cnt = ;
t[k].val = x;t[k].key = rand();
return ;
}
t[k].siz++;
if (t[k].val==x) t[k].cnt ++;
else if (x > t[k].val) {
Insert(rson,x);
if (t[rson].key < t[k].key) leftturn(k);
}
else {
Insert(lson,x);
if (t[lson].key < t[k].key) rightturn(k);
}
}
void Delete(int &k,int x) {
if (k==) return ;
if (t[k].val==x) {
if (t[k].cnt > ) {
t[k].cnt--;t[k].siz--;return ;
}
if (lson * rson == ) k = lson + rson;
else if (t[lson].key < t[rson].key) {
rightturn(k);Delete(k,x);
}
else {
leftturn(k);Delete(k,x);
}
}
else if (x > t[k].val) {
t[k].siz--;Delete(rson,x);
}
else {
t[k].siz--;Delete(lson,x);
}
}
int getk(int k,int x) {
if (k==) return ;
if (t[k].val==x) return t[lson].siz + ;
else if (x > t[k].val)
return t[lson].siz + t[k].cnt + getk(rson,x);
else return getk(lson,x);
}
int getkth(int k,int x) {
if (k==) return ;
if (x <= t[lson].siz) return getkth(lson,x);
else if (x > t[lson].siz + t[k].cnt)
return getkth(rson,x-t[lson].siz-t[k].cnt);
else return t[k].val;
}
void getpre(int k,int x) {
if (k==) return ;
if (t[k].val < x) ans = k,getpre(rson,x);
else getpre(lson,x);
}
void getsuc(int k,int x) {
if (k==) return ;
if (t[k].val > x) ans = k,getsuc(lson,x);
else getsuc(rson,x);
} int main() {
int n = read();
while (n--){
int opt = read(),x = read();
if (opt==) Insert(Root,x);
else if (opt==) Delete(Root,x);
else if (opt==) printf("%d\n",getk(Root,x));
else if (opt==) printf("%d\n",getkth(Root,x));
else if (opt==) ans = ,getpre(Root,x),printf("%d\n",t[ans].val);
else ans = ,getsuc(Root,x),printf("%d\n",t[ans].val);
}
return ;
}

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

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

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

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

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

  3. 算法模板——平衡树Treap 2

    实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...

  4. 普通平衡树Treap(含旋转)学习笔记

    浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...

  5. 2021.12.06 平衡树——Treap

    2021.12.06 平衡树--Treap https://www.luogu.com.cn/blog/HOJQVFNA/qian-xi-treap-ping-heng-shu 1.二叉搜索树 1.1 ...

  6. hiho #1325 : 平衡树·Treap

    #1325 : 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? ...

  7. hiho一下103周 平衡树·Treap

    平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二 ...

  8. 【山东省选2008】郁闷的小J 平衡树Treap

    小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他面临着被解雇的危险,这也正是他所郁闷的.具体说来,书架由N ...

  9. Hihocoder 1325 平衡树·Treap(平衡树,Treap)

    Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...

  10. HihoCoder 1325 平衡树·Treap

    HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...

随机推荐

  1. MVC FileResult

    你如何将文件传送给用户取决于你最开始如何存储它,如果你将文件存入数据库,你会用流的方式将文件返还给用户,如果你将文件存在硬盘中,你只需要提供一个超链接即可,或者也可以以流的方式.每当你需要以流的方式将 ...

  2. .net程序员业余Android开发赚点外快(介绍一下自己的经验)

    记得是11年10月份开始研究android的,当时还不会java,听说android比较火,自己也买了个垃圾android机,平时工作也不是特别忙,于是我就突发奇想,想试试做一下android应用可不 ...

  3. 什么是JavaScript

    来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=30&cid= JavaScript是一种松散类型的客户端脚本语言,在用户浏览器中执 ...

  4. Eclipse的安装与使用

    1安装 下载 http://www.eclipse.org 安装 (最好下载解压版的,不用安装) 安装目录中,不要出现空格与中文 例如,解压到:D:\codetool 2项目的创建 双击运行.exe文 ...

  5. 在CentOS7上源码安装php7--Install php7 from source on CentOS7

    首先下载php源码包并解压: # wget http://cn2.php.net/get/php-7.0.9.tar.gz/from/this/mirror # .tar.gz # cd php- 然 ...

  6. python+selenium之中类/函数/模块的简单介绍和方法调用

    # coding=utf-8 class ClassA (object): string1 = "这是一个字符串." def instancefunc(self): print ( ...

  7. 转 winfrom如何通过http来进行通信,并且通过传递json格式的数据可接受json格式的数据

    string username = this.textBox1.Text; string password = this.textBox2.Text; string AA = HttpUtility. ...

  8. Spark 配置整理

    Spark 的配置有很多,这里一方面总结一下官方文档中的内容,一方面将网上查到的资料中用到的针对特定问题的配置整理一下. 先看一下官网的配置:http://spark.apache.org/docs/ ...

  9. git clone 和 download 不一样,能用git clone 就用git clone,download的代码,经常出现安装bug

    git clone 和 download 不一样,能用git clone 就用git clone,download的代码,经常出现安装bug

  10. ListView适配器Adapter介绍与优化

    一.ListView与Adapter的关系 ListView是Android开发过程中较为常见的组件之一,它将数据以列表的形式展现出来.一般而言,一个ListView由以下三个元素组成: 1.View ...