multiplication algorithm , time complexity O (NLOGN)
SA Save relative size subscript from small to large
Understanding lsd,x arrays, SA arrays
Char s[maxn];int sa[maxn],t[maxn],t2[maxn],c[maxn],n;void build_sa (int m) {//lsd radix sort int *x=t,*y=t2;//x array save rank/ /String length is 1, that is, the size of each element is sorted for (int i=0;i<m;++i) c[i]=0;//count array empty for (int i=0;i<n;++i) c[x[i]=s[i]]++;//statistics occurrences for ( int i=1;i<m;++i) c[i]+=c[i-1];//compute prefix and for (int i=n-1;i>=0;--i) Sa[--c[x[i]]]=i;//sa Save the subscript for each element from small to large for (int k =1;k<=n;k<<=1) {//k is the length of the substring to sort//Sort second keyword int p=0; Y[] From small to large save the second keyword subscript for (int i=n-k;i<n;++i) y[p++]=i;//A string starting from the N-k bit, the second keyword is 0 for (int i=0;i<n;++i) if (sa[i]>=k) y[p++]=sa[i]-k; Rank talent with only the subscript sa[i] string that is greater than k as the next line of the second keyword//sort first keyword//x[y[i]] is a reference to the first keyword On the basis of LSD the second sort to be based on the first for (int i=0;i<m;++i) c[i]=0;//count array empty for (int i=0;i<n;++i) c[x[y[i]]]++;//statistics rank appears times for (int i=1;i<m;++i) c[i]+=c[i-1];//prefix and for (int i=n-1;i>=0;--i) Sa[--c[x[y[i]]]]=y[i]//sa[] Save double keyword subscript p=1;swap (x, y) from small to large, x[sa[0]]=0;//swap x, y array x[] array save rank value from 0 to n-1 (0 to P) for (int i=1;i< ; n;++i) {x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]? p-1:p++;//Note p-1//Because P is a count R Ank values differ by the number of strings, so double keyword the same string as the same as rank} if (p>=n) break; The rank value of P string is different, the size is established when p>=n, and the SA does not change the maximum value of m=p;//for the next cardinality order if it is multiplied later.}}
————————————————————————————————————--————————
————————————————————————————————————————————
void Build_sa () {int *x=t,*y=t2; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) c[x[i]=y[i]]++; for (int i=1;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) {int p=0; for (int i=n-k;i<n;++i) y[p++]=i; for (int i=0;i<n;++i) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) c[x[y[i]]]++; for (int i=1;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; int P=0;swap (x, y); x[sa[0]]=0; for (int i=1;i<n;++i) {x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k] p-1:p++; } if (p>=n) break; M=p; }}int m;int Cmp_suffix (char *pattern,int p) {return strncmp (pattern,s+sa[p],m);} int find (char *p) {M=strlen (P); if (Cmp_suffix (p,0) <0) return-1; if (Cmp_suffix (p,n-1) >0) return-1; int l=0,r=n-1; while (l<=r) {int mid=l+ (R-L)/2; int Res=cmp_suffix (P,MID); if (!res) return mid; if (res>0) l=mid+1; if (res<0) r=mid-1; } return-1;} /* Set suffix (k) to be the suffix of the previous suffix (i-1). Their longest common prefix is h[i-1]. Then suffix (k+1) will be in front of suffix (i) (h[i-1]>1 is required here, assuming h[i-1]≤1, the original is clearly established) and suffix (k+1) and suffix (i) the longest common prefix is h[i-1]- 1, so suffix (i) and the longest common prefix of the suffix in its previous name is at least h[i-1]-1. Calculated in accordance with H[1],h[2],......,h[n] order. And using the properties of H array, the time complexity can be reduced to O (n).*/void Get_height () {for (int i=0;i<n;++i) rank[sa[i]]=i; int k=0; for (int i=0;i<n;++i) {if (k) k--; int j=sa[rank[i]]-1; while (S[j+k]==s[i+k]) k++; Height[rank[i]]=k; }}
Suffix array suffix array