p3369跳表代替平衡树
生活随笔
收集整理的這篇文章主要介紹了
p3369跳表代替平衡树
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接、
在洛谷題解里沒看到有寫跳表的。自己看了看跳表琢磨了一下,調了一份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跳表代替平衡树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scheme语言 入门语法
- 下一篇: PHP安装rabbitmq扩展