链接一下题目: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) 题解的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Sql 语句中使用参数

    using System; using System.Data; using System.Data.SqlClient; namespace ConsoleApplication2 { public ...

  2. UNIX网络编程总结一

    客户与服务器通信使用TCP在同一网络通信时,大致按下面的方式通信:client→TCP→IP→以太网驱动程序→以太网→以太网驱动程序→IP→TCP→server.若不在同一网络则需要路由器连接. 客户 ...

  3. 04Dropout

    不加Dropout,训练数据的准确率高,基本上可以接近100%,但是,对于测试集来说,效果并不好: 加上Dropout,训练数据的准确率可能变低,但是,对于测试集来说,效果更好了,所以说Dropout ...

  4. 02tensorflow非线性回归以及分类的简单实用,softmax介绍

    import tensorflow as tf import numpy as np import matplotlib.pyplot as plt # 使用numpy生成200个随机点 x_data ...

  5. more 分页显示文件内容

    1.命令功能 more 分页显示文件内容 2.语法格式 more  option file 参数说明 参数 参数说明 -num 指定屏幕显示大小为num行 +num 从行号num号开始显示 -s 把连 ...

  6. ACM-ICPC 2015 Changchun Preliminary Contest J. Unknown Treasure (卢卡斯定理+中国剩余定理)

    题目链接:https://nanti.jisuanke.com/t/A1842 题目大意:给定整数n,m,k,其中1≤m≤n≤1018,k≤10, 然后给出k个素数,保证M=p[1]*p[2]……*p ...

  7. stream benchmark 交叉编译 on psoc

    之前有研究过这个,居然忘记了,看来确实是老了,没有盘过来. 如何下载,见 linux下载网页上的文件夹以及删除文件(stream) 出现了好几个问题 1. error while loading sh ...

  8. 剖析 Vue.js 内部运行机制 (1)

    1. new Vue() 之后. Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周 期.事件. props. methods. data. computed ...

  9. 前端每日实战:30# 视频演示如何用纯 CSS 创作一个晃动的公告板

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/wjZoGV 可交互视频教程 此视频 ...

  10. Java 逻辑运算符相关解析

    问:定简单说说 Java 中 & 与 && 有什么区别?| 与 || 呢? 答:& 是位运算符,&& 是布尔逻辑运算符,| 与 || 类似同理.在进行逻 ...