Skip Table Detail Note
See the comment code specifically
luogup3369:https://www.luogu.org/recordnew/show/11782419
1#include <bits/stdc++.h>2 #defineRepeat (a,b,c,d) for (int a=b;a<=c;a+=d)3 using namespacestd;4 structnode{5 intNxt,dwn,jmp,val;6}a[100000*4];7 intAl =0, N,first;8 Const intMAXDEP =9, INF =1e9;9InlinevoidBuild () {//called at the beginning of the program to construct a DEP=MAXDEP tableTen for(RegisterintI=1; i<=maxdep;i++) {//Build Start Node OneA[++AL].NXT = Maxdep + i;//point to last node A if(I! =1) A[al].dwn = al-1;//non-first node points to the next down node - ElseA[al].dwn =-1;//last one -A[AL].JMP =0; a[al].val =-inf;//assignment, a[al].jmp can be arbitrarily assigned. the } -First = Al;//point to first node - for(RegisterintI=1; i<=maxdep;i++){ -A[++AL].NXT =-1;//same + if(I! =-1) A[al].dwn = al-1; -a[al].jmp = Inf;a[al].val =INF; + } A } at //we then maintain the now pointer. -InlineintDfs_insert (intXintNow,intDepintINSDEP) {//for constant optimization, do not call Find_k_rank_and_p first to find a position, but directly to the recursive position. - if(DEP = =0)return 0;//Border -RegisterintLEN_JMP =0;//the length of our hands from now on. - while(x > A[a[now].nxt].val) len_jmp + = a[now].jmp, now = A[NOW].NXT;//* * Remember, all skip list searches are open intervals! ** -Registerintlft_jmp = Dfs_insert (x,a[now].dwn,dep-1, INSDEP);//to the next level . in if(Dep > INSDEP) a[now].jmp++;//if the specified number of layers is not reached, just now the JMP pointer increases - Else{ toA[++AL].NXT = A[NOW].NXT;A[NOW].NXT = Al;a[al].dwn = al-1; a[al].val = x;//Maintain pointers +a[al].jmp = A[NOW].JMP-LFT_JMP;A[NOW].JMP = lft_jmp +1;//Maintain now - } the returnLEN_JMP + lft_jmp;//returns the number of skipped layers. * } $InlinevoidInsertintx) {Panax NotoginsengRegisterintINSDEP =1, random = rand () << -|rand ();//* * Don't ever Rand come to Rand, thief slow! - while(random%4==0) insdep++,random/=4;d Fs_insert (X,FIRST,MAXDEP,INSDEP);//the fastest 4-layer test the } +Inline pair<int,int> find_k_rank_and_p (intx) { ARegisterintnow = First,len =0, dep = MAXDEP;//find rank for x and return now pointer (all open interval) the while(Dep >0){ + while(x > A[a[now].nxt].val) len + = a[now].jmp, now = A[NOW].NXT;//you can walk . -dep--;//number of maintenance layers $ if(DEP = =0) Break;//in order to maintain now, once dep==0 is break; $now =A[now].dwn; - } - returnMake_pair (len+1, now);//Len is the opening interval, to +1. the } -InlinevoidDelintx) {WuyiRegisterintRank = find_k_rank_and_p (x). First,now = First,len =0, dep = MAXDEP;//Delete the first to find out where to delete, it must be guaranteed not to delete more. the while(Dep >0){ - while(x > A[a[now].nxt].val) len + = a[now].jmp, now = A[NOW].NXT;//Find Wu if(A[a[now].nxt].val = = x && len + a[now].jmp = = rank)//Be del -a[now].jmp = a[now].jmp + a[a[now].nxt].jmp-1, a[now].nxt = A[A[NOW].NXT].NXT;//Maintain now Pointer About Elsea[now].jmp--; $now =A[now].dwn; -dep--; - } - } AInlineintFind_rank_val (intx) { +Registerintnow = First,len =0, DEP =MAXDEP; the while(Dep >0){ - while(x > Len +a[now].jmp) $Len + = a[now].jmp, now = A[NOW].NXT;//you can jump. thedep--; the if(DEP = =0) Break; thenow =A[now].dwn; the } - returnA[a[now].nxt].val;//return value in } the intMain () { the Srand (Time (NULL)); About build (); thescanf"%d",&n); the for(intI=1; i<=n;i++){ theRegisterintopt,x; +scanf"%d%d",&opt,&x); - if(opt = =1) insert (x);//Insert the if(opt = =2) del (x);//DeleteBayi if(opt = =3) printf ("%d\n", Find_k_rank_and_p (x). first);//find the X-number position the if(opt = =4) printf ("%d\n", Find_rank_val (x));//find values for rank x the if(opt = =5) printf ("%d\n", A[find_k_rank_and_p (x). Second].val);//finding the precursor to X - if(opt = =6) printf ("%d\n", A[a[find_k_rank_and_p (x+1). Second].nxt].val);//to find the suffix of x - } the}
Skip List
Skip List-Skip table detailed note, constant small