Suffix array DA (multiplication) algorithm for sa[n] and Rank[n] (Time O (nlogn), Space O (N))
Sa[i]: Indicates the suffix starting subscript in the first position
Rank[i]: Indicates the suffix suffix (i) ranked in the first
Height[i]: LCP value representing sa[i-1] and Sa[i]
H[i]: Represents suffix (i) with its top-ranked LCP value
Const intN =int(2E5) +Ten;intcmpint*r,intAintBintl) { return(R[a]==r[b]) && (r[a+l]==r[b+l]);}//used to compare the first keyword with the second keyword,//The special place is, when preprocessing, r[n]=0 (less than the preceding characters)intWa[n],wb[n],ws[n],wv[n];intRank[n],height[n];voidCAOint(RNint*sa,intNintm) {//here n is more than 1 of the input n, a manually added character used to avoid CMP time out of bounds inti,j,p,*x=wa,*y=wb,*T; for(i=0; i<m;i++) ws[i]=0; for(i=0; i<n;i++) ws[x[i]=r[i]]++; for(i=1; i<m;i++) ws[i]+=ws[i-1]; for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i;//preprocessing length is 1 for(j=1, p=1;p <n;j*=2, m=p)//The SA that has been calculated for the length of J, to find 2*j SAS { for(p=0, i=n-j;i<n;i++) y[p++]=i;//Special handling without a second keyword for(i=0; i<n;i++)if(sa[i]>=j) Y[p++]=sa[i]-j;//using the length J, sort by the second keyword for(i=0; i<n;i++) wv[i]=X[y[i]]; for(i=0; i<m;i++) ws[i]=0; for(i=0; i<n;i++) ws[wv[i]]++; for(i=1; i<m;i++) ws[i]+=ws[i-1]; for(i=n-1; i>=0; i--) Sa[--ws[wv[i]]]=y[i];//Base Sort Section for(t=x,x=y,y=t,p=1, x[sa[0]]=0, i=1; i<n;i++) X[sa[i]]=CMP (y,sa[i-1],sa[i],j)? p1:p + +;//update rank array x[], pay attention to the same }}voidCalheight (int*r,int*sa,intN) {//here n is the actual length inti,j,k=0;//the legal range of height[] is 1-n, where 0 is the end-added character for(i=1; i<=n;i++) rank[sa[i]]=i;//rank according to SA for(i=0;i<n; height[rank[i++]] = k)//definition: h[i] = height[Rank[i]] for(k?k--:0, j=sa[rank[i]-1]; R[I+K]==R[J+K]; k++);//optimize the calculation height process according to H[i] >= h[i-1]-1}CharStr[n];intSa[n];intMain () {CharStr[n]; scanf ("%s", str); intn =strlen (str); Str[n]=0; Da (str,sa,n+1, -);//Note that this is n+1 because a trailing character is added to distinguish the comparisoncalheight (str,sa,n);}
DC3 Template (Time complexity O (N), Spatial complexity O (3N))
#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#include<algorithm>using namespacestd;Const intMAXN =int(3E6) +Ten;Const intN =MAXN; #defineF (x) ((x)/3+ ((x)%3==1?0:TB))#defineG (x) ((x) <TB? ( x) *3+1: (((x)-TB) *3+2)intWA[MAXN],WB[MAXN],WV[MAXN],WS[MAXN]; intC0 (int*r,intAintb) {returnr[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];} intC12 (intKint(RNintAintb) {if(k==2)returnr[a]<r[b]| | R[A]==R[B]&&C12 (1, r,a+1, B +1); Else returnr[a]<r[b]| | r[a]==r[b]&&wv[a+1]<wv[b+1];} voidSortint*r,int*a,int*b,intNintm) {inti; for(i=0; i<n;i++) wv[i]=R[a[i]]; for(i=0; i<m;i++) ws[i]=0; for(i=0; i<n;i++) ws[wv[i]]++; for(i=1; i<m;i++) ws[i]+=ws[i-1]; for(i=n-1; i>=0; i--) b[--ws[wv[i]]]=A[i]; return; } voidDC3 (int*r,int*sa,intNintM//same meaning as Da { intI,j,*rn=r+n,*san=sa+n,ta=0, tb= (n+1)/3, tbc=0, p; R[n]=r[n+1]=0; for(i=0; i<n;i++)if(i%3!=0) wa[tbc++]=i; Sort (R+2, wa,wb,tbc,m); Sort (R+1, wb,wa,tbc,m); Sort (r,wa,wb,tbc,m); for(p=1, Rn[f (wb[0])]=0, i=1; i<tbc;i++) rn[f (Wb[i])=C0 (r,wb[i-1],wb[i])? p1:p + +; if(p<tbc) DC3 (rn,san,tbc,p); Else for(i=0; i<tbc;i++) san[rn[i]]=i; for(i=0; i<tbc;i++)if(SAN[I]<TB) wb[ta++]=san[i]*3; if(n%3==1) wb[ta++]=n-1; Sort (r,wb,wa,ta,m); for(i=0; i<tbc;i++) wv[wb[i]=g (San[i])]=i; for(i=0, j=0, p=0; I<ta && j<tbc;p++) Sa[p]=C12 (wb[j]%3, R,wa[i],wb[j])? wa[i++]:wb[j++]; for(; i<ta;p++) sa[p]=wa[i++]; for(; j<tbc;p++) sa[p]=wb[j++]; return; }
Suffix array template