1 ///后缀数组模板 2 sa[i]表示所有后缀按字典数排序后以s[i] 3 开始的后缀排在第i位。height[i]表示字典数为i和i-1后缀的 4 的最长串的前缀。 5 int s[mx],sa[mx],t[mx],t2[mx],c[mx],n; 6 int rank[mx],height[mx]; 7 8 void build_sa(int m) 9 { 10 int i,*x=t,*y=t2; 11 for (i=0;i<m;i++) c[i]=0; 12 for (i=0;i<n;i++) c[x[i]=s[i]]++; 13 for (i=1;i<m;i++) c[i]+=c[i-1]; 14 for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 15 for (int k=1;k<=n;k<<=1) 16 { 17 int p=0; 18 for (i=n-k;i<n;i++) y[p++]=i; 19 for (i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k; 20 for (i=0;i<m;i++) c[i]=0; 21 for (i=0;i<n;i++) c[x[y[i]]]++; 22 for (i=1;i<m;i++) c[i]+=c[i-1]; 23 for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; 24 swap(x,y); 25 p=1; 26 x[sa[0]]=0; 27 for (i=1;i<n;i++) 28 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 29 if (p>=n) break; 30 m=p; 31 } 32 } 33 34 void getHeight() 35 { 36 int i,j,k=0; 37 for (i=0;i<n;i++) rank[sa[i]]=i; 38 for (i=0;i<n;i++) 39 { 40 if (k) k--; 41 int j=sa[rank[i]-1]; 42 while (s[i+k]==s[j+k]) k++; 43 height[rank[i]]=k; 44 } 45 }