参考视频:https://www.bilibili.com/video/BV1wt411u7xL?t=1142讲的特别好!
注释都在代码中了

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;struct node{   //这里记录重复结点用的是cnt这个变量1代表这个数有一个,2代表这个数有两个。。。int l,r;int val,size,cnt;
}spl[maxn];
int cnt,root;void new_node(int &now,int &val){  //新建结点now=++cnt;spl[now].val=val;spl[now].size++;spl[now].cnt++;
}
void update(int now){   //更新sizespl[now].size=spl[spl[now].l].size+spl[spl[now].r].size+spl[now].cnt;
}
void zig(int &now){   //右旋int l=spl[now].l;spl[now].l=spl[l].r;spl[l].r=now;now=l;update(spl[now].r),update(now);
}
void zag(int &now){   //左旋int r=spl[now].r; //把他右子树的结点暂存一下,一会需要以右孩子为根节点spl[now].r=spl[r].l; //把根节点右子树的左子树挂在原来根节点的上右子树上spl[r].l=now; //把原来的根节点挂在原来的右子树(现在的根节点)上去now=r;   //现在的根节点更新update(spl[now].l),update(now); //检查树是否需要更新
}void splaying(int x,int &y){   //if(x==y) return;   //如果到了我们指定的结点,return//主要是通过递归进行伸展操作,//通过从根节点不断递归到自己想要悬上去的结点//不过缺点就是常数可能比较大,但是好写一些int &l=spl[y].l,&r=spl[y].r;if(x==l) zig(y);else if(x==r) zag(y);else{if(spl[x].val<spl[y].val){if(spl[x].val<spl[l].val)splaying(x,spl[l].l),zig(y),zig(y);     //zigzig情况else splaying(x,spl[l].r),zag(l),zig(y);    //zagzig情况}else{if(spl[x].val>spl[r].val)splaying(x,spl[r].r),zag(y),zag(y);     //zagzag情况else splaying(x,spl[r].l),zig(r),zag(y);    //zigzag情况}}
}
void del_node(int now){   //找到删除的结点并将其删除splaying(now,root);  //先把要删除的结点延申到根节点//看看次数是否重复了,如果重复了结点直接-1即可(看内存池是如何定义的)if(spl[now].cnt>1){spl[now].size--;spl[now].cnt--;}else if(spl[root].r){  //找一下后继,建议看一下up的视频,讲的很清晰(17min开始看)int temp=spl[root].r;while (spl[temp].l) temp=spl[temp].l;splaying(temp,spl[root].r);spl[spl[root].r].l=spl[root].l;root=spl[root].r;update(root);}else root=spl[root].l;
}
void del(int &now,int val){   //找到那个删除的结点if(spl[now].val==val) del_node(now);else if(val<spl[now].val) del(spl[now].l,val);else del(spl[now].r,val);
}
void insert(int &now,int val){  //插入if(!now) new_node(now,val),splaying(now,root);  //新建结点并插入else if(val<spl[now].val) insert(spl[now].l,val);else if(val>spl[now].val) insert(spl[now].r,val);else spl[now].size++,spl[now].cnt++,splaying(now,root);
}
int get_rank(int val){int now=root,rank=1;//往树的右孩子走,同时减去加上他小的个数//(他的左子树的数都比他小,所以他的总排名肯定要比左边的所有数都高,//所以先用rank加上左数大小)while (now){if(spl[now].val==val){rank+=spl[spl[now].l].size;splaying(now,root);break;}if(val<=spl[now].val) now=spl[now].l;else{rank+=spl[spl[now].l].size+spl[now].cnt;now=spl[now].r;}}return rank;
}
int get_num(int rank){int now=root;while (now){int lsize=spl[spl[now].l].size;if(lsize+1<=rank&&rank<=lsize+spl[now].cnt){  //如果找到了直接breaksplaying(now,root);break;}else if(lsize>=rank) now=spl[now].l;else{//往树的右孩子走,同时减去比他小的个数//(他的左子树的数都比他小,所以直接减去左子树的大小)rank-=lsize+spl[now].cnt;now=spl[now].r;}}return spl[now].val;
}int main()
{int n;cin>>n;for(int i=0;i<n;i++){int ch,x;scanf("%d%d",&ch,&x);if(ch==1) insert(root,x);if(ch==2) del(root,x);if(ch==3) printf("%d\n",get_rank(x));if(ch==4) printf("%d\n",get_num(x));if(ch==5) printf("%d\n",get_num(get_rank(x)-1));if(ch==6) printf("%d\n",get_num(get_rank(x+1)));}return 0;
}

平衡二叉树-splay c/c++代码实现相关推荐

  1. 平衡二叉树-AVL c/c++代码实现

    参考:https://www.bilibili.com/video/BV1rt411j7Ff?t=703大佬视频 一份代码,代码中有注释,对应着洛谷的**P3369 [模板]普通平衡树** /*Kee ...

  2. 平衡二叉树的旋转及其代码实现

    平衡二叉树的构造问题以及为了维护它的平衡所要进行的LL旋转.RR旋转.LR旋转.RL旋转. 一.平衡二叉树的构造 node *insert(node *root, int x) {if (root = ...

  3. python实现平衡二叉树_LeetCode 110. 平衡二叉树 | Python

    # 110. 平衡二叉树 --- 题目来源:力扣(LeetCode)[https://leetcode-cn.com/problems/balanced-binary-tree](https://le ...

  4. 洛谷 P2596 [ZJOI2006]书架 (splay)

    题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...

  5. bzoj2733 永无乡 splay树的启发式合并

    https://vjudge.net/problem/HYSBZ-2733 给一些带权点,有些点是互相连通的, 然后给出2种操作,在两点间加一条边,或者询问一个点所在的连通块内的第k小值的编号 并查集 ...

  6. 数据结构-平衡二叉树(AVL树)

    目录 1,平衡二叉树的介绍 1.1,二叉排序树存在的问题 1.2,平衡二叉树 1.3,平衡二叉树的创建 1.4,平衡二叉树的查找 2,代码实现 2.1,平衡二叉树的节点类型 2.2,LL旋转(单右旋转 ...

  7. 关于splay的一些说明

    前言 splay出现的背景 它的操作 push_up rotate splay find insert next delete findkth main 前言 暑假快过完了,大家感觉是不是很棒!gay ...

  8. C++实现二叉树相关问题(先序遍历,中序遍历,后序遍历,层序遍历,搜索二叉树、平衡二叉树、满二叉树、完全二叉树的判断,最低公共祖先,二叉树的序列化和反序列化)

    目录 题目一 二叉树递归和非递归遍历 题目二 如何完成二叉树的宽度(也叫层序)遍历(常见题目:求一棵二叉树的宽度) 题目四 如何判断一棵二叉树是搜索二叉树(BST)? 题目四 如何判断一棵二叉树是平衡 ...

  9. 二叉排序树转换为平衡二叉树

    二叉排序树的缺点 二叉排序树是在插入数据是一个一个对比然后进行插入,如果给出一串数字为[1,2,3,4,5,6,7,8] 则它的排序结果为:这样的二叉树不仅性能会降低(没有链表存储的性能高),而且针对 ...

最新文章

  1. Science | COVID-19大流行期间,研究重点应放在高质量研究
  2. MySQL内核月报 2015.01-MySQL · 捉虫动态· InnoDB自增列重复值问题
  3. sizeof()与strlen()
  4. thinkphp curd的事务回滚 一看就会
  5. 论文浅尝 | 用增强学习进行推理:问答与知识库完善(KBC)
  6. java商品管理系统_【Java Web】简易商品信息管理系统——首个Web项目
  7. css定位能用android,绝对的CSS定位显示android html上的空白区域
  8. 新增一个主键自增长_使用技巧之——MyBatis如何返回插入主键
  9. access百度翻译 get_求助,百度翻译后我还是不知道怎么解决这个问题
  10. 从架构到代码:软件开发的七个新趋势 | 凌云时刻
  11. 【Python】基于Python的百度迁徙3——城内出行强度(附代码)
  12. 点我—— ASP.NETCORE 安装CentOS
  13. 怎么启用对远程服务器的访问,未启用对服务器的远程访问怎么办
  14. python入门教材带视频_Python全套,从入门到进阶。视频,电子书
  15. 论文精读:MobileNetV2: Inverted Residuals and Linear Bottlenecks
  16. 关于【ROM制作工具】的那点事
  17. 【R1CS to QAP】
  18. 主板没有rgb接口怎么接灯_DIY只为玩游戏?主板配上RGB灯让机箱发光
  19. IT项目管理小组分工情况
  20. net.sf.json.exception:Unquotted String错误,解决办法。

热门文章

  1. k-近邻算法之距离度量
  2. 数据结构-图-遍历-搜索
  3. ISDN,俗称一线通!
  4. R-C3D 视频活动检测
  5. 防抖技术 | OpenCV实现视频稳流
  6. LOJ6435 PKUSC2018 星际穿越
  7. MYSQL转换编码的解决方法
  8. 如何实现最佳的跨平台游戏体验?Unity成亮解密实时渲染技术!
  9. nginx配置image_filter生成缩略图
  10. 《Python for Data Analysis》之 Series