后缀数组模板

 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 }
原文地址:https://www.cnblogs.com/pblr/p/5720276.html