在洛谷题解里没看到有写跳表的。自己看了看跳表琢磨了一下,调了一份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;
}