安利splay讲解:

[洛谷日报第62期]Splay简易教程

【模板】普通平衡树(luogu)

Description

题目描述

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

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

输入格式

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

输出格式

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

Code

#include <iostream>
using namespace std;
const int N=1e5+;
//1:插入xx数
//2:删除xx数(若有多个相同的数,因只删除一个)
//3:查询xx数的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
//4:查询排名为xx的数
//5:求xx的前驱(前驱定义为小于xx,且最大的数)
//6:求xx的后继(后继定义为大于xx,且最小的数)
int n,x,opt,cnt[N],size[N],val[N],tot,ch[N][],rt,fa[N];
struct Splay
{
void push_up(int x)
{
size[x]=size[ch[x][]]+size[ch[x][]]+cnt[x];
}
bool get(int x)
{
return x==ch[fa[x]][];
}
void clear(int x)
{
size[x]=ch[x][]=ch[x][]=cnt[x]=val[x]=fa[x]=;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],wh=get(x);
fa[ch[x][wh^]]=y;
ch[y][wh]=ch[x][wh^];
ch[x][wh^]=y;
fa[x]=z,fa[y]=x;
if(z) ch[z][y==ch[z][]]=x;
push_up(y),push_up(x);
}
void splay(int x)
{
for(int f=fa[x];f=fa[x],f;rotate(x))
if(fa[f]) rotate(get(f)==get(x)?f:x);
rt=x;
}
int nxt()
{
int now=ch[rt][];
while(ch[now][]) now=ch[now][];
return now;
}
int pre()
{
int now=ch[rt][];
while(ch[now][]) now=ch[now][];
return now;
}
int rk(int x)
{
int res=,now=rt;
while()
{
if(x<val[now]) now=ch[now][];
else
{
res+=size[ch[now][]];
if(x==val[now])
{
splay(now);
return res+;
}
res+=cnt[now],now=ch[now][];
}
}
}
int kth(int x)
{
int now=rt;
while()
{
if(ch[now][] && x<=size[ch[now][]]) now=ch[now][];
else
{
x-=size[ch[now][]]+cnt[now];
if(x<=) return val[now];
now=ch[now][];
}
}
}
void ins(int x)
{
if(!rt)
{
rt=++tot,cnt[tot]=,val[tot]=x;
push_up(tot);
return ;
}
int now=rt,par=;
while()
{
if(val[now]==x)
{
cnt[now]++;
push_up(now),push_up(par);
splay(now);
return ;
}
par=now,now=ch[now][x>val[now]];
if(!now)
{
cnt[++tot]=,val[tot]=x,fa[tot]=par;
ch[par][x>val[par]]=tot;
push_up(tot),push_up(par);
splay(tot);
return ;
}
}
}
void del(int x)
{
rk(x);
if(cnt[rt]>) cnt[rt]--,push_up(rt);
else if(!ch[rt][] && !ch[rt][]) clear(rt),rt=;
else if(!ch[rt][])
{
int now=rt;
rt=ch[rt][],fa[rt]=;
clear(now);
}
else if(!ch[rt][])
{
int now=rt;
rt=ch[rt][],fa[rt]=;
clear(now);
}
else
{
int x=pre(),now=rt;
splay(x);
fa[ch[now][]]=rt;
ch[rt][]=ch[now][];
clear(now);
push_up(rt);
}
}
}tree;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
while(n--)
{
cin>>opt>>x;
if(opt==) tree.ins(x);
else if(opt==) tree.del(x);
else if(opt==) cout<<tree.rk(x)<<endl;
else if(opt==) cout<<tree.kth(x)<<endl;
else if(opt==) tree.ins(x),cout<<val[tree.pre()]<<endl,tree.del(x);
else if(opt==) tree.ins(x),cout<<val[tree.nxt()]<<endl,tree.del(x);
}
return ;
}

【模板】普通平衡树(权值splay)的更多相关文章

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

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

  2. [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]

    题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...

  3. [BZOJ3600] 没有人的算术 [重量平衡树+权值线段树]

    题面 传送门 思路 这道题目是陈立杰论文<重量平衡树和后缀平衡树在信息学奥赛中的应用 >中关于重量平衡树维护序列排名算法的一个应用 具体方法为:令根节点保存一个实数区间$[0,1]$ 若当 ...

  4. cogs 1829. [Tyvj 1728]普通平衡树 权值线段树

    1829. [Tyvj 1728]普通平衡树 ★★★   输入文件:phs.in   输出文件:phs.out   简单对比时间限制:1 s   内存限制:1000 MB [题目描述] 您需要写一种数 ...

  5. [ZJOI2006]书架(权值splay)

    [ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...

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

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

  7. BZOJ_3224 Tyvj 1728 普通平衡树 【离散化+权值线段树】

    一 题面 Tyvj 1728 普通平衡树 二 分析 比较明显是可以用平衡二叉搜索树(splay)做的. 用权值线段树做,前提就是要先离散化,因为权值线段树维护的值域信息. 板子. 三 AC代码 #in ...

  8. 【权值分块】bzoj3224 Tyvj 1728 普通平衡树

    权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...

  9. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

随机推荐

  1. js获取url参数值的方式

    定义方法: function getParam(paramName) { paramValue = ""; isFound = false; paramName = paramNa ...

  2. 【软件】Gimp内容识别填充开启工具1.0

    *源文件起初存于Gimp-Registry,后因服务器维护成本问题,Gimp将原服务器中所有文件迁移至GimpGithub *博主只是将原插件中的内容识别填充功能进行打包处理,方便大家一键启用. 下载 ...

  3. jenkins安装自动部署

    1.1简介: 开源项目,一个可扩展的持续集成引擎.提供了一种易于使用的持续集成系统,能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性.还做到持 ...

  4. Java提供的JDBC标准- 六大步骤

    JDBC 1.//加载驱动 class.forname 2.//创建连接connection 3.//创建 管道流 statement或  preparestatement预处理4.//执行sql语句 ...

  5. ES6学习----let、const、解构赋值、新增字符串、模板字符串、Symbol类型、Proxy、Set

    这篇es6的学习笔记来自于表哥 表严肃,是我遇到过的讲课最通透,英文发音最好听的老师,想一起听课就去这里吧 https://biaoyansu.com/i/hzhj1206 ES6就是JS6,JS的第 ...

  6. win10开启我的第一个32位汇编程序

    遥想当年,上学期间,汇编程序,从未成功.今又试之,终成功,遂记录. Hello.asm文件如下: . .model flat,stdcall option casemap:none include w ...

  7. 洛谷P1189 SEARCH 题解 迭代加深

    题目链接:https://www.luogu.com.cn/problem/P1189 题目大意: 给你一个 \(n \times m\) 的矩阵,其中有一些格子可以走,一些各自不能走,然后有一个点是 ...

  8. HDU5179 beautiful number 题解 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5179 题目大意: 给你一个数 \(A = a_1a_2 \cdots a_n\) ,我们称 \(A\) ...

  9. Web基础了解版12-上传下载

    上传 两个步骤: 用户在页面中选择要上传的文件,然后将请求提交到Servlet Servlet收到请求,解析用户上传的文件,然后将文件存储到服务器 上传文件表单 <form action=&qu ...

  10. 傅立叶变换—DFT

    背景:最近看到实验室其他同学在用傅立叶变换解决问题,我也想通过并行来解决这个问题,所以看了一下傅立叶变换的东西,感觉涵盖的东西还能多,我只是初步做了一下了解(一定很片面,但是我主要是为了应用它,主要了 ...