后缀数组(倍增) 时间nlogn 空间n

模板   

 1 struct SuffixArray{
 2     int sa[maxn];//排名为i的后缀的起始下标
 3     int Rank[maxn];//起始下标为i的后缀排名
 4     int height[maxn];//排名为i和i-1的最长公共前缀
 5     int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
 6 
 7     int cmp(int *r, int a,int b,int l){//双关键字排序的比较
 8         return r[a]==r[b] && r[a+l]==r[b+l];
 9     }
10 
11     void da(int *r,int n,int m){
12         ///r表示原数组,sa表示排名为i的下标,n表示r的大小+1,m表示字符的范围
13         ///注意使用时如果r的大小为n,那么应传入n+1
14         //x为第一关键字,y为第二关键字
15         int i,k,p,*x = wa,*y = wb,*t;
16         //长度为1时的基数排序
17         for(i=0;i<m;i++) ws[i] = 0;
18         for(i=0;i<n;i++) ws[x[i] = r[i]] ++;
19         for(i=0;i<m;i++) ws[i] += ws[i-1];
20         for(i=n-1;i>=0;i--) sa[-- ws[x[i]]] = i;
21         //主要循环,k倍增
22         for(k=1,p=1; p<n; k*=2, m=p){
23             //以下两行代码实现了对第二关键字的排序
24             for(p=0,i=n-k;i<n;i++) y[p++] = i;
25             for(i=0;i<n;i++){
26                 if(sa[i] >= k){
27                     y[p++] = sa[i] - k;
28                 }
29             }
30             //提取出每个子串的第一关键字
31             for(i=0;i<n;i++){
32                 wv[i] = x[y[i]];
33             }
34             //基数排序
35             for(i=0;i<m;i++) ws[i]=0;
36             for(i=0;i<n;i++) ws[wv[i]]++;
37             for(i=1;i<m;i++) ws[i]+=ws[i-1];
38             for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
39             t=x,x=y,y=t;
40             for(p=1,x[sa[0]]=0,i=1;i<n;i++)
41                 x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?p-1:p++;
42         }
43     }
44 
45     //求rank数组与height数组
46     void cal(int *r,int n){
47         ///此处传入n即可
48         int i,j,k=0;
49         for(i=1;i<=n;i++) Rank[sa[i]] = i;
50         for(i=0;i<n;i++){
51             if(k > 0) k--;
52             j=sa[Rank[i]-1];
53             while(r[i+k] == r[j+k]) k++;
54             height[Rank[i]] = k;
55         }
56 
57         //for(i=0;i<n;height[Rank[i++]]=k)
58         //for(k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);
59     }
60 
61     /*使用方法
62     da(r,n+1,m);
63     cal(r,n);*/
64 }SA;

 

posted @ 2017-08-20 17:25  yZi  阅读(198)  评论(0编辑  收藏  举报