标签:
后缀数组,解决字符串问题的有利工具,本题代码为倍增SA算法
具体解释详见2009年国家集训队论文
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 9 using namespace std; 10 11 int str[110000]; 12 int Barrel[2][110000],U[110000],Tmp[110000],SA[110000],H[110000]; 13 char r[110000]; 14 15 void Calc_H(const int & n,const int * Rank) 16 { 17 int i,j,k=0; 18 for(i=0;i<n;H[Rank[i++]]=k) 19 for(k?k--:0,j=SA[Rank[i]-1];str[i+k]==str[j+k];++k); 20 return ; 21 } 22 23 bool cmp(const int * s,const int a,const int b,const int l) 24 { 25 return s[a]==s[b] && s[a+l]==s[b+l]; 26 } 27 28 int* Get_SA(const int & n,int m) 29 { 30 int i,j,p,*x=Barrel[0],*y=Barrel[1]; 31 memset(U,0,sizeof(U)); 32 for(i=0;i<n;++i)U[x[i]=str[i]]++; 33 for(i=1;i<m;++i)U[i]+=U[i-1]; 34 for(i=n-1;i>=0;--i)SA[--U[x[i]]]=i; 35 36 for(j=1,p=1;p<n;j<<=1,m=p) 37 { 38 for(p=0,i=n-j;i<n;++i)y[p++]=i; 39 for(i=0;i<n;++i)if(SA[i]>=j)y[p++]=SA[i]-j; 40 for(i=0;i<n;++i)Tmp[i]=x[y[i]]; 41 for(i=0;i<m;++i)U[i]=0; 42 for(i=0;i<n;++i)U[Tmp[i]]++; 43 for(i=1;i<m;++i)U[i]+=U[i-1]; 44 for(i=n-1;i>=0;--i)SA[--U[Tmp[i]]]=y[i]; 45 for(swap(x,y),p=1,x[SA[0]]=0,i=1;i<n;++i) 46 x[SA[i]]=cmp(y,SA[i-1],SA[i],j)?p-1:p++; 47 } 48 Calc_H(n,x); 49 return x; 50 } 51 52 int main() 53 { 54 int i,n; 55 scanf("%s",r); 56 n=strlen(r); 57 for(i=0;i<n;++i)str[i]=r[i]; 58 59 Get_SA(n+1,256); 60 61 for(i=1;i<=n;++i)printf("%d ",SA[i]+1); 62 printf("\n"); 63 for(i=2;i<=n;++i)printf("%d ",H[i]); 64 65 return 0; 66 }
在计算H数组的时候因为在计算SA数组的程序中x所代表的数组中就是Rank数组,所以不需要重新计算
[UOJ#35] [UOJ后缀数组模板题] 后缀排序 [后缀数组模板]
标签:
原文地址:http://www.cnblogs.com/Gster/p/4977946.html