专栏文章
跳跃表学习笔记
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio7i1k3
- 此快照首次捕获于
- 2025/12/02 14:37 3 个月前
- 此快照最后确认于
- 2025/12/02 14:37 3 个月前
代码:
CPP#include<bits/stdc++.h>
using namespace std;
const int inf = 0x7f7f7f7f;
const int N = 1e5+10,MAXL = 10;// 若概率为0.5,则改为20
int n,lv,tot[MAXL],sz;//最高层数 当前层到当前点的节点数 节点个数
typedef struct node{
int val;//值
int di[MAXL];//与下一个节点之间的距离
struct node* forward[MAXL];//(链表意义上的)后继指针数组
}*nodeptr;
nodeptr head,updata[MAXL+1];//头结点 访问路径中每层的最高节点
void init(){
srand(time(0));
lv = 0;
head = new(node);
for(int i = 0;i < MAXL;++ i){
head->forward[i] = NULL;
head->di[i] = 0;
}
head->val = -inf;
return;
}
inline int randlevel(){
int lay = 1;
while((rand()&1) && (rand()&1) && lay < MAXL)
++ lay;
return lay;
}
int find(int val){//小于val的元素个数
nodeptr p = head;
tot[lv] = 0;
for(int i = lv-1;i >= 0;-- i){
tot[i] = tot[i+1];
while(p->forward[i] && p->forward[i]->val < val)
tot[i] += p->di[i],p = p->forward[i];
updata[i] = p;
}
return tot[0];
}
void insert(int val){//插入元素
nodeptr p = new(node);
find(val);
p->val = val;
int lay = randlevel();
if(lay > lv){
for(int i = lv;i < lay;++ i){
updata[i] = head;
updata[i]->di[i] = sz;
tot[i] = 0;
}
lv = lay;
}
for(int i = 0;i < lay;++ i){
p->forward[i] = updata[i]->forward[i];
p->di[i] = updata[i]->di[i] - (tot[0] - tot[i]);
updata[i]->forward[i] = p;
updata[i]->di[i] = tot[0] - tot[i] + 1;
}
for(int i = lay;i < lv;++ i)
++ updata[i]->di[i];
++ sz;
return;
}
void remove(int val){//删除元素
find(val);
nodeptr p = updata[0]->forward[0];
for(int i = 0;i < lv;++ i){
if(updata[i]->forward[i] == p){
updata[i]->di[i] += p->di[i]-1;
updata[i]->forward[i] = p->forward[i];
}else -- updata[i]->di[i];
}
while(lv && !head->forward[lv-1])
-- lv;
delete(p);
-- sz;
return;
}
int kth(int k){//求第k小数
nodeptr p = head;
for(int i = lv-1;i >= 0;-- i)
while(p->forward[i] && p->di[i] < k)
k -= p->di[i],p = p->forward[i];
return p->forward[0]->val;
}
int rnk(int val){
nodeptr p = head;
int res = 0;
for(int i = lv-1;i >= 0;-- i){
while(p->forward[i] && p->forward[i]->val < val)
res += p->di[i],p = p->forward[i];
}
return res + 1;
}
nodeptr getpre(int val){//前驱
nodeptr p = head;
for(int i = lv-1;i >= 0;-- i){
while(p->forward[i] && p->forward[i]->val < val)
p = p->forward[i];
}
return p;
}
nodeptr getnxt(int val){//后继
nodeptr p = head;
for(int i = lv-1;i >= 0;-- i){
while(p->forward[i] && p->forward[i]->val <= val)
p = p->forward[i];
}
return p->forward[0];
}
int main(){
// ios::sync_with_stdio(0);
// cin.tie(0);
cin >> n;
init();
while(n --){
int op,x;
cin >> op >> x;
switch(op){
case 1: insert(x);break;
case 2: remove(x);break;
case 3: cout << rnk(x) << '\n';break;
case 4: cout << kth(x) << '\n';break;
case 5: cout << getpre(x)->val << '\n';break;
case 6: cout << getnxt(x)->val << '\n';
}
// cout << "Right";
// getchar();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...