luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#define lst long long
#define rg register
#define N 500050
#define Inf 2147483647
using namespace std; int use,root,tot;//操作数,根节点编号,树中元素总和
struct T{
int cnt;//这个数相等的数的数量
int size;//这棵子树上一共有几个元素
int fa,v;//父亲节点,当前点的权值
int ch[];//左(0)右(1)孩子
}ljl[N];//平衡树 inline int read()
{
rg int s=,m=;char ch=getchar();
while(ch!='-'&&(ch<''||ch>''))ch=getchar();
if(ch=='-')m=-,ch=getchar();
while(ch>=''&&ch<='')s=(s<<)+(s<<)+ch-'',ch=getchar();
return s*m;
} inline void Pushup(rg int now)//更新节点size的操作
{
ljl[now].size=ljl[ljl[now].ch[]].size+ljl[ljl[now].ch[]].size+ljl[now].cnt;
//当前节点的size是左孩子子树的size加上右孩子子树的size加上本节点相等的数的数量
} inline void rotate(rg int x)//把x往上转
{//定义:x的相对位置为x属于y的?孩子
rg int y=ljl[x].fa;//父亲
rg int z=ljl[y].fa;//祖父
rg int k=ljl[y].ch[]==x;//x的相对位置
ljl[z].ch[ljl[z].ch[]==y]=x;//把x转到y的位置上去
ljl[x].fa=z;//x的爸爸变成了z
ljl[y].ch[k]=ljl[x].ch[k^];//y的x的相对位置的那个孩子变成x的x的相对位置的另一个孩子
ljl[ljl[x].ch[k^]].fa=y;//……的爸爸变成y
ljl[x].ch[k^]=y;//x的相对位置的另一个孩子变成y
ljl[y].fa=x;//y的爸爸变成x
Pushup(x),Pushup(y);//更新一下节点数量
} inline void splay(rg int x,rg int goal)//把x转到goal下面,如果goal=0,那么就是转到根节点
{
while(ljl[x].fa!=goal)//如果x的父亲不是goal,目标没有达成,就要继续转
{
rg int y=ljl[x].fa;//父亲
rg int z=ljl[y].fa;//祖父
if(z!=goal)//如果z存在的话
{
(x==ljl[y].ch[])^(y==ljl[z].ch[])?rotate(x):rotate(y);
//如果x和y分别是y和z的同一孩子,就把y往上转
//如果x和y分别是y和z的不同孩子,就把x往上转
}
rotate(x);//最后一定会要把x在网上转一次
}
if(!goal)root=x;//更新根节点
} void Insert(rg int x)//插入x
{
rg int now=root,fa=;//从根开始找,根的父亲是0
while(ljl[now].v!=x&&now)//只要还没有找到这个数字,且当前这个位置有数,就继续找
{
fa=now;//爸爸变成现在的节点
now=ljl[now].ch[x>ljl[now].v];//如果x比now大,就找now的右孩子,小则左孩子
}
if(now)ljl[now].cnt++;//如果存值的位置存在,就直接在计数器上加1
else//否则
{
now=++tot;//增加一个新位置
if(fa)ljl[fa].ch[x>ljl[fa].v]=now;//如果父亲存在(我不是根),那我的父亲的儿子是我
ljl[now].v=x;//权值
ljl[now].fa=fa;//父亲
ljl[now].cnt=;//计数器
ljl[now].size=;//子树大小
ljl[now].ch[]=ljl[now].ch[]=;//没有孩子
}
splay(now,);//把当前位置转到根节点,以维持树的平衡
} inline void find(rg int x)//找x的位置,把它转到根节点,方便之后的计算
{
rg int now=root;//从根开始找
if(!root)return;//如果是空树,还找个屁
while(x!=ljl[now].v&&ljl[now].ch[x>ljl[now].v])//如果还没有找到那个点,且我还有符合的儿子
now=ljl[now].ch[x>ljl[now].v];//就跳转到我的儿子继续找
splay(now,);//转到树根去
} inline int Next(rg int x,rg int f)//找x的前驱(0)后继(1)
{
find(x);//先找到x的位置,可能树顶不是x,是和x值接近的那个元素
int now=root;//从根开始找
if(ljl[now].v>x&&f)return now;//如果大于x且我们要找后继,那就是他了
if(ljl[now].v<x&&!f)return now;//如果小于x且我们要找前驱,那就是他了
now=ljl[now].ch[f];//那我们从符合条件的儿子开始跳
while(ljl[now].ch[f^])now=ljl[now].ch[f^];//不断的往最优的方向跳
return now;//返回位置
} inline void Delete(rg int x)//删掉x
{
rg int qq=Next(x,);//找到前驱
rg int hj=Next(x,);//找到后继
splay(qq,),splay(hj,qq);//把前驱转到树根,把后继转到前驱下面
int del=ljl[hj].ch[];//那么x就是后继的左儿子
if(ljl[del].cnt>)//如果x的计数器大于1
{
ljl[del].cnt--;//让x的计数器--
splay(del,);//转到树根保持平衡
}
else ljl[hj].ch[]=;//直接删除x
} inline int kth(rg int x)//找第x小的数
{
rg int now=root;//从根开始找
if(ljl[now].size<x)return ;//如果排名都超过总数了…………
while()//嘿嘿,一直找
{
rg int ls=ljl[now].ch[];//左孩子
if(ljl[ls].size+ljl[now].cnt<x)//如果排名比左孩子总元素数和与我相等的数总和还大
{
x-=ljl[ls].size+ljl[now].cnt;//就减去前面的元素数
now=ljl[now].ch[];//去右孩子上找这个排名
}
else
if(ljl[ls].size>=x)now=ls;//如果左孩子里包括它
else return ljl[now].v;//那就在这个点上了,返回
}
} int main()
{
use=read();
Insert(Inf),Insert(-Inf);
for(rg int i=;i<=use;++i)
{
rg int opt=read(),x=read();
if(opt==)Insert(x);
if(opt==)Delete(x);
if(opt==)find(x),printf("%d\n",ljl[ljl[root].ch[]].size);
if(opt==)printf("%d\n",kth(x+));
if(opt==)printf("%d\n",ljl[Next(x,)].v);
if(opt==)printf("%d\n",ljl[Next(x,)].v);
}
return ;
}
luoguP3369[模板]普通平衡树(Treap/SBT) 题解的更多相关文章
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- [luogu P3369]【模板】普通平衡树(Treap/SBT)
[luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369
[模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...
- 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...
- 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...
- 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...
- P3369 【模板】普通平衡树 Treap
P3369 [模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询 ...
- 算法模板——平衡树Treap 2
实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728) 这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣 ...
随机推荐
- Vue简单封装axios—解决post请求后端接收不到参数问题
1.在src/下新建api文件夹,api/下新建index.js和public.js 在public.js中: import axios from 'axios'; import qs from 'q ...
- ES基本原理
Elasticsearch是基于一款高性能的.可扩展的信息检索工具库Lucene构建的强大的搜索引擎,在很多情况,它也被作为NoSql数据库并取得了很好的效果,下面介绍下ES的基本概念,映射到数据库的 ...
- md5sum 计算和校验文件的md5值
1. 命令功能 md5算法一般用于检查文件完整性, 2. 语法格式 md5sum [option] [file] 参数 参数说明 -b 以二进制模式读入文件 -t 以文本模式读入文件 -c 用来从 ...
- hdu4348 To the moon (可持久化线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4348 题目大意:给定含有n个数的序列,有以下四种操作 1.C l r d:表示对区间[l,r]中的数加 ...
- ssm框架整合抽取BaseDao接口
import java.io.Serializable; import java.util.List; /** * DAO基础操作模板 * * @param <T> 泛型 */ publi ...
- INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
[转] https://www.mobibrw.com/2016/3949 adb install 一个apk错误: INSTALL_FAILED_ALREADY_EXISTS 应用已存在,使用 ad ...
- Centos中文语言乱码解决方法
vim /etc/locale.conf 添加:LANG="zh_CN.UTF-8" 执行一下source /etc/locale.conf,使刚修改的文件生效
- 关于SQL Server系统数据库详解
介绍这里我们介绍SQL Sever内部的系统数据库的作用和用户数据库之间联系,关于SQL Sever如何管理用户数据库的原理,对于每个数据库开发人员和DBA都是必须掌握的. SQL Sever系统数据 ...
- shapefile文件数据结构
头部 点 线 面 序号 x,y,... 线 序号 1,2 面 序号 1,2,3 拓扑检查 ... <GIS数据结构与算法>
- 20180823-Java包
Java 包(package) 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包 ...