【模板】普通平衡树(权值splay)
安利splay讲解:
【模板】普通平衡树(luogu)
Description
题目描述
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
- 插入 xx 数
- 删除 xx 数(若有多个相同的数,因只删除一个)
- 查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
- 查询排名为 xx 的数
- 求 xx 的前驱(前驱定义为小于 xx,且最大的数)
- 求 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)的更多相关文章
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- [BZOJ3196] 二逼平衡树 [权值线段树套位置平衡树]
题面 洛咕题面 思路 没错我就是要不走寻常路! 看看那些外层位置数据结构,必须二分的,$O(n\log^3 n)$的做法吧! 看看那些cdq分治/树状数组套线段树的,空间$O(n\log^2 n)$挤 ...
- [BZOJ3600] 没有人的算术 [重量平衡树+权值线段树]
题面 传送门 思路 这道题目是陈立杰论文<重量平衡树和后缀平衡树在信息学奥赛中的应用 >中关于重量平衡树维护序列排名算法的一个应用 具体方法为:令根节点保存一个实数区间$[0,1]$ 若当 ...
- cogs 1829. [Tyvj 1728]普通平衡树 权值线段树
1829. [Tyvj 1728]普通平衡树 ★★★ 输入文件:phs.in 输出文件:phs.out 简单对比时间限制:1 s 内存限制:1000 MB [题目描述] 您需要写一种数 ...
- [ZJOI2006]书架(权值splay)
[ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- BZOJ_3224 Tyvj 1728 普通平衡树 【离散化+权值线段树】
一 题面 Tyvj 1728 普通平衡树 二 分析 比较明显是可以用平衡二叉搜索树(splay)做的. 用权值线段树做,前提就是要先离散化,因为权值线段树维护的值域信息. 板子. 三 AC代码 #in ...
- 【权值分块】bzoj3224 Tyvj 1728 普通平衡树
权值分块和权值线段树的思想一致,离散化之后可以代替平衡树的部分功能. 部分操作的时间复杂度: 插入 删除 全局排名 全局K大 前驱 后继 全局最值 按值域删除元素 O(1) O(1) O(sqrt(n ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
随机推荐
- spring boot 多数据源加载原理
git代码:https://gitee.com/wwj912790488/multiple-data-sources DynamicDataSourceAspect切面 必须定义@Order(-10) ...
- Android SDK目录具体结构及Android源码的具体结构
Android SDK目录具体结构 1. add-ons:这里面保存着附加库,比如Google Maps,当然你如果安装了OphoneSDK,这里也会有一些类库在里面. 2. docs:这里面是And ...
- 38.CSS
转载:https://www.cnblogs.com/yuanchenqi/articles/5977825.html css概述 CSS是Cascading Style Sheets的简称,中文称为 ...
- 什么是激励函数 (Activation Function)
relu sigmoid tanh 激励函数. 可以创立自己的激励函数解决自己的问题,只要保证这些激励函数是可以微分的. 只有两三层的神经网络,随便使用哪个激励函数都可以. 多层的不能随便选择,涉及梯 ...
- 一篇长文说 git 基础
版本管理在产品级开发中是非常重要的一个部分,它涉及到团队协作,且影响到产品最终的发布.上线以及测试环节,当前最流行的版本控制系统是 git.git 内容非常多,本文尽量克制地来介绍 git 的基础内容 ...
- Java高级特性——流
以上就是这段时间学习完流的知识以后我的总结,.mmap文件可以去我的github上获取:https://github.com/xiaozhengyu/StudyNotes.git
- vue iView table中render渲染
<template> <div class="srm-page"> <el-form ref="form" :model=&quo ...
- Hadoop以及组件介绍
一.背景介绍 在接触过大数据相关项目的时候常常都会听到Hadoop这个东西,简单来说,他是一个用分布式计算来处理大数据的开源软件,下面包含了许多的组件和子项目,这篇文章将会介绍Hadoop的原理以及一 ...
- POJ 1458 Common Subsequence (动态规划)
题目传送门 POJ 1458 Description A subsequence of a given sequence is the given sequence with some element ...
- Spring中常见的设计模式——适配器模式
一.适配器模式的应用场景 适配器模式(Adapter Pattern)是指将一个类的接口转换成用户期待的另一个接口,使原本接口不兼容的类可以一起工作,属于构造设计模式. 适配器适用于以下几种业务场景: ...