#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;// Splay
class Splay{#define root T[0].son[1]  //T[0]为超级根,树根为超级根的右孩子private:struct Tree{  //一个节点只存储一个数值,一个数值只由一个点存储int fa, son[2]/*0 左,1 右*/, v/*当前节点数值*/, sum/*以当前节点为根的树中所有数值的数量*/, recy/*当前点的数值的数量*/;}T[100005];int ctp/*数值数量*/, ctn/*节点编号*/;void update(int k){  //更新sumT[k].sum = T[T[k].son[1]].sum+T[T[k].son[0]].sum+T[k].recy;}int identify(int k){  //识别自己是左(右)孩子return T[T[k].fa].son[0]==k?0:1;}void connect(int s, int f, int lr){  //建立两点间父子关系T[s].fa = f, T[f].son[lr] = s;}void rotate(int k){  //左(右)旋操作int p = T[k].fa, q = T[p].fa;int lrk = identify(k), lrp = identify(p);int b = T[k].son[lrk^1];connect(b, p, lrk), connect(p, k, lrk^1), connect(k, q, lrp);update(p), update(k);}void splay(int k, int to){  //核心 将点 k 旋转到点 toto = T[to].fa; int up;while(T[k].fa != to){up = T[k].fa;if(T[up].fa == to) rotate(k);else{identify(k)==identify(up)?rotate(up):rotate(k);rotate(k);}}}int creat(int v, int fa){  //新建点T[++ctn].fa = fa, T[ctn].v = v;T[ctn].sum = T[ctn].recy = 1;return ctn;}void destory(int k){  //摧毁点T[k].fa = T[k].sum = T[k].son[1] = T[k].son[0] = T[k].recy = 0;}int find(int v){  //查找点int k = root, next;while(T[k].v != v){next = v<T[k].v?0:1;if(!T[k].son[next]) return 0;k = T[k].son[next];}splay(k, root);return k;}int build(int v){  //没有splay的push(见下方push)if(!ctp++){root = creat(v, 0);return 0;}int k = root, next;while(T[k].v != v){T[k].sum++;next = v<T[k].v?0:1;if(!T[k].son[next]) return T[k].son[next] = creat(v, k);k = T[k].son[next];}T[k].sum++;T[k].recy++;return k;}public:void push(int v){  //插入一个数值splay(build(v), root);}void pop(int v){  //删除一个数值int k = find(v);if(!k) return;ctp--;if(T[k].recy > 1){T[k].recy--;T[k].sum--;return;}if(!T[k].son[0]) connect(T[k].son[1], 0, 1);else if(!T[k].son[1]) connect(T[k].son[0], 0, 1);else{int ls = T[k].son[0];while(T[ls].son[1]) ls = T[ls].son[1];splay(ls, T[k].son[0]);int rs = T[k].son[1];connect(rs, ls, 1), connect(ls, 0, 1);update(ls);}destory(k);}int rank(int v){  //查询数值 v 的排名int k = root, ans = 0;if(!root) return 0;while(T[k].v != v){if(v < T[k].v) k = T[k].son[0];else{ans += T[T[k].son[0]].sum+T[k].recy;k = T[k].son[1];}if(!k) return 0;}ans += T[T[k].son[0]].sum+1;splay(k, root);return ans;}int atrank(int x){  //查询排名为 x 的数值if(x > ctp) return -INF;int k = root, p;while(1){p = T[T[k].son[0]].sum+T[k].recy;if(x>T[T[k].son[0]].sum && x<=p) break;if(x < p) k = T[k].son[0];else{x -= p;k = T[k].son[1];} }splay(k, root);return T[k].v;}int upper(int v){  //查询数值 v 的后继int k = root, ans = INF;while(k){if(T[k].v>v && T[k].v<ans) ans = T[k].v;if(v < T[k].v) k = T[k].son[0];else k = T[k].son[1];}return ans;}int lower(int v){  //查询数值 v 的前驱int k = root, ans = -INF;while(k){if(T[k].v<v && T[k].v>ans) ans = T[k].v;if(v > T[k].v) k = T[k].son[1];else k = T[k].son[0];}return ans;}#undef root
}W;// main
int main(){int n, a, b;scanf("%d", &n);while(n--){scanf("%d%d", &a, &b);if(a == 1) W.push(b);else if(a == 2) W.pop(b);else if(a == 3) printf("%d\n", W.rank(b));else if(a == 4) printf("%d\n", W.atrank(b));else if(a == 5) printf("%d\n", W.lower(b));else printf("%d\n", W.upper(b));}return 0;
}

转载于:https://www.cnblogs.com/bosswnx/p/10570787.html

【code】Splay 模板相关推荐

  1. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  2. 伸展树 Splay 模板

    学习Splay的时候参考了很多不同的资料,然而参考资料太杂的后果就是模板调出来一直都有问题,尤其是最后发现网上找的各种资料均有不同程度的错误. 好在啃了几天之后终于算是啃下来了. Splay也算是平衡 ...

  3. 【BZOJ - 3224】普通平衡树(Splay模板题)

    题干: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入x数 2. 删除x数(若有多个相同的数,因只删除一个) 3. 查询x数的排名(若有多个相同的数,因输出最 ...

  4. Splay(splay模板)

    题目描述 给定一个长度为 n 的整数序列,初始时序列为 {1,2,-,n−1,n}. 序列中的位置从左到右依次标号为 1∼n. 我们用 [l,r] 来表示从位置 l 到位置 r 之间(包括两端点)的所 ...

  5. vs code vue模板创建

    摆图 其他模板创建,依照此法即可. 转载于:https://blog.51cto.com/11mihu/1926917

  6. Duan2baka的Splay模板!(区间翻转)

    BZOJ[3223] Tyvj 1729 文艺平衡树 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3223 Splay区间翻转 代码如下: ...

  7. Duan2baka的Splay模板!(二叉搜索树)

    BZOJ[3224] Tyvj 1728 普通平衡树 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3224 用Splay搞了一发-. (以 ...

  8. VS Code vue 模板

    我们希望每次新建.vue文件后,VSCODE能够根据配置,自动生成我们想要的内容. 打开VSCODE编辑器,依次选择"文件 -> 首选项 -> 用户代码片段",此时,会 ...

  9. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

最新文章

  1. RhinoMock入门(7)——Do,With和Record-playback
  2. 叶明回归IBM 负责大中华区合作伙伴业务
  3. Docker容器间Link单向通信
  4. Entity framework WhereInExtension
  5. 华北电力大学的计算机类专业排名,2018年华北电力大学王牌专业排行榜,考生和家长们都好好看看!...
  6. 5.11 学习日记,首页banner做好了
  7. 数组翻转_LeetCode刷题实战151:翻转字符串里的单词
  8. php 日历哪个好,简单的PHP日历
  9. 【联系】—— Beta 分布与二项分布、共轭分布
  10. css鼠标滑过变大,css 鼠标移上去会变大(示例代码)
  11. BASLER巴斯勒线扫相机使用流程
  12. 海思3559开发环境搭建:从这里开始
  13. JS中的this是什么,this的四种用法
  14. 外泌体,顶刊新宠丨一文 get 研究套路!
  15. docker版MySQL经常性崩溃_mysql docker容器经常崩溃
  16. ZYNQ-AXI DMA IP简介
  17. Unity特效基础:粒子效果面板
  18. 决策树(三)--完整总结(ID3,C4.5,CART,剪枝,替代)
  19. 男士保持肌肉的六窍门
  20. unicloud云开发---uniapp云开发(一)---服务空间创建以及部署一个云函数

热门文章

  1. 皮肤的实时3S渲染(OpenGL + GLSL)
  2. Netty 系列三(ByteBuf).
  3. Java浮点数内存存储
  4. 《软件工艺师:专业、务实、自豪》一第3章
  5. NeHe OpenGL教程 第二十一课:线的游戏
  6. 随心篇第九期:我不愿一无所有
  7. windows 加域
  8. WMI使用的WIN32_类库名
  9. [转载] 杜拉拉升职记——20 两位同僚
  10. gradle使用技巧之全局变量