题目链接、

在洛谷题解里没看到有写跳表的。自己看了看跳表琢磨了一下,调了一份A掉的代码

多加了一个数组用来存跳过了几个元素,前开后闭也就是(]

代码写的真丑

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7,maxlevel = 25;
int sknext[maxn][maxlevel],tot,head,tail;
int skval[maxn];
int skbk[maxn][maxlevel];
int stk[maxn],top;
int randLevel(int ans = 0){while(rand()&1&&ans<maxlevel)ans++;return ans;
}
int newNode(int &p,int key = 0){p = top?stk[top--]:++tot;skval[p] = key;for(int i=maxlevel-1;i;i--)skbk[p][i] = 0;skbk[p][0] = 1;
}
void freeNode(int p){stk[++top] = p;
}
void Insert(int key){int p = head,k = randLevel(),tmp;int update[maxlevel],cnt[maxlevel];for(int i=maxlevel-1;~i;i--){cnt[i] = 0;while(sknext[p][i]^tail&&skval[sknext[p][i]]<key)p = sknext[p][i],cnt[i] += skbk[p][i];update[i] = p;}newNode(tmp,key);for(int i=maxlevel-1;i>k;i--){int bf = update[i],af = sknext[bf][i];skbk[af][i] ++;}for(int i = 0;i<=k;i++){int bf = update[i],af = sknext[bf][i];if(i){skbk[tmp][i] += cnt[i-1]+1;cnt[i] += cnt[i-1];skbk[af][i] -= skbk[tmp][i]-1;}sknext[tmp][i] = af;sknext[bf][i] = tmp;}
}
void Erase(int key){int p = head;int update[maxlevel];for(int i=maxlevel-1;~i;i--){while(sknext[p][i]^tail&&skval[sknext[p][i]]<key)p = sknext[p][i];update[i] = p;}freeNode(sknext[p][0]);for(int i = maxlevel-1;~i;i--){int bf = update[i],nw = sknext[bf][i],af = sknext[nw][i];if(skval[sknext[update[i]][i]] == key){skbk[af][i] += skbk[nw][i]-1;sknext[bf][i] = af;}else{//if(skbk[nw][i])skbk[nw][i]--;}}
}
void init(){srand(time(0));newNode(head);newNode(tail);for(int i=maxlevel-1;~i;i--){sknext[head][i] = tail;}
}
int findRank(int key){int p = head,res = 0;for(int i=maxlevel-1;~i;i--){while(sknext[p][i]^tail&&skval[sknext[p][i]]<key)p = sknext[p][i],res += skbk[p][i];}return skval[sknext[p][0]] == key?res+1:-1;
}
int findVal(int Rank){int p = head,res = 0;for(int i=maxlevel-1;~i;i--){while(sknext[p][i]^tail){int tp = sknext[p][i];if(res + skbk[tp][i] > Rank)break;p = tp;//cout<<skval[p]<<endl;res += skbk[p][i];}}return res == Rank?skval[p]:-1;
}
int findPre(int key){int p = head;for(int i=maxlevel-1;~i;i--){while(sknext[p][i]^tail&&skval[sknext[p][i]]<key)p = sknext[p][i];}return skval[p];
}
int findAft(int key){int p = head;for(int i=maxlevel-1;~i;i--){while(sknext[p][i]^tail&&skval[sknext[p][i]]<=key)p = sknext[p][i];}return skval[sknext[p][0]];
}
int n,opt,x;
int main(){init();scanf("%d",&n);while(n--){scanf("%d%d",&opt,&x);if(opt == 1)Insert(x);else if(opt == 2)Erase(x);else if(opt == 3)printf("%d\n",findRank(x));else if(opt == 4)printf("%d\n",findVal(x));else if(opt == 5)printf("%d\n",findPre(x));else printf("%d\n",findAft(x));}return 0;
}

p3369跳表代替平衡树相关推荐

  1. Redis Zset的实现为什么用跳表,而不用平衡树?

    之前写过一篇 Redis 数据类型的底层数据结构的实现,其中提到,ZSet 对象的底层数据结构实现之一是跳表. 然后,有读者就问:为什么不使用平衡树(如红黑树.AVL 树)? 我们先来了解下跳表,再来 ...

  2. 跳表SkipList

    1.聊一聊跳表作者的其人其事 2. 言归正传,跳表简介 3. 跳表数据存储模型 4. 跳表的代码实现分析 5. 论文,代码下载及参考资料 <1>. 聊一聊作者的其人其事  跳表是由Will ...

  3. 二叉树 跳表_漫谈 LevelDB 数据结构(一):跳表(Skip List)

    早对 LevelDB 有所耳闻,这次心血来潮结合一些资料粗略过了遍代码,果然名不虚传--绝对是不世出的工艺品!如果你对存储感兴趣.如果你想优雅使用C++.如果你想学习如何架构项目,都推荐来观摩一下.谷 ...

  4. 一种数据结构 跳表skiplist

    跳表是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的. 下载地址 : http://download ...

  5. 插入的数据不能时时查询到_漫谈 LevelDB 数据结构(一):跳表(Skip List)

    早对 LevelDB 有所耳闻,这次心血来潮结合一些资料粗略过了遍代码,果然名不虚传--绝对是不世出的工艺品!如果你对存储感兴趣.如果你想优雅使用C++.如果你想学习如何架构项目,都推荐来观摩一下.谷 ...

  6. HashMap为什么用红黑树而不用跳表?redis的zset为什么用跳表而不用红黑树?

    问题引入 前些天在思考zset为什么用跳表而不用红黑树时,自然想到了HashMap为什么用红黑树而不用跳表,做了一些查询和考虑,以此记录结果 redis的zset为什么用跳表而不用红黑树? 1.跳表的 ...

  7. java数据结构红黑树上旋下旋_存储系统的基本数据结构之一: 跳表 (SkipList)

    在接下来的系列文章中,我们将介绍一系列应用于存储以及IO子系统的数据结构.这些数据结构相互关联又有着巨大的区别,希望我们能够不辱使命的将他们分门别类的介绍清楚.本文为第一节,介绍一个简单而又有用的数据 ...

  8. Redis 为什么用跳表而不用平衡树?

    本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...

  9. Redis 为什么用跳表而不用平衡树

    Redis 为什么用跳表而不用平衡树? 本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用s ...

  10. 图解|深入理解跳表及其在Redis中的应用

    跳跃链表及其应用是非常热门的问题,深入了解其中奥秘大有裨益,不吹了,快开始品尝这美味的知识吧! 跳跃链表的基本概念 初识跳表 跳跃列表是一种数据结构.它允许快速查询一个有序连续元素的数据链表.跳跃列表 ...

最新文章

  1. MyBatis 几个常用的 jdbcType数据
  2. h5启动原生APP总结
  3. DNS的几个基本概念:
  4. 使用brew安装软件
  5. TCP三次握手(待细研究)
  6. 高级工作流模式深入业务场景分析(1)——多路合并
  7. Android应用插件式开发解决方法
  8. 第七章:在Spark集群上使用文件中的数据加载成为graph并进行操作(3)
  9. java 随机获取4个数字_java入门-验证码 今天查到的一个简单随机生成4位数字的验证码-jsp...
  10. Linux命令大全:grep命令
  11. linux脚本取消空格,Shell去除空格和空行的方法
  12. tar命令打包并压缩指定的文件夹并且排除指定的文件
  13. JAVA RPC(二)序列化协议杂谈
  14. STM32输出PWM波形以及实现LED呼吸灯
  15. Vmware黑屏解决
  16. iOS软件开发实现类似微信上传图片选择
  17. EASYOPS系列|谨慎!勿让持续交付变成bug自动化发布
  18. mac无法使用80端口问题
  19. layui文件上传接口后端具体实现SpringMVC
  20. sticky footer布局,页面不足一屏底部footer固定在视窗底部,否则底部footer自动向下顺延

热门文章

  1. centos7/8配置secondary ip
  2. vue + web 前端访问后端,跨域问题解决方案
  3. UVALive 6198 A Terribly Grimm Problem
  4. 如何将excel转换成word文档图文教程
  5. 对待新知识、新领域的心态——好奇、批判、独孤求败
  6. Flixel横板游戏制作教程(四)— RandomLevels
  7. python中bytearray函数_Python bytearray() 函数
  8. 【Openbravo开发】Openbravo windows开发环境搭建
  9. python gtk_python-gtk学习笔记
  10. idea破解到2100年