標籤:尾碼數組 string out 模板 www span algorithm namespace www.
現在來看倍增演算法是非常好理解的。
直接放一篇blog寫的挺好的:http://www.cnblogs.com/zinthos/p/3899725.html
雖然理論複雜度是$O(nlogn)$,但其中各種細節最佳化確實十分有必要的。
給自己放一個倍增的模板,有空填DC3的坑
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int n,m; 6 char s[1000010]; 7 int rk[1000010],sa[1000010],tmp[1000010],c[1000010]; 8 void outint(int x){ 9 if(x>=10) outint(x/10);10 putchar(x%10+‘0‘);11 }12 bool inline cmp(int *r,int a,int b,int l){13 return r[a]==r[b]&&r[a+l]==r[b+l];14 }15 void Getsa(){16 m=127;17 for(int i=0;i<=m;i++) c[i]=0;18 for(int i=1;i<=n;i++) c[rk[i]=s[i]]++;19 for(int i=1;i<=m;i++) c[i]+=c[i-1];20 for(int i=n;i>=1;i--) sa[c[rk[i]]--]=i;21 for(int i=1;i<=n;i<<=1){22 int p=0;23 for(int j=n-i+1;j<=n;j++) tmp[++p]=j;24 for(int j=1;j<=n;j++) if(sa[j]>i) tmp[++p]=sa[j]-i;25 for(int j=0;j<=m;j++) c[j]=0;26 for(int j=1;j<=n;j++) c[rk[tmp[j]]]++;27 for(int j=1;j<=m;j++) c[j]+=c[j-1];28 for(int j=n;j>=1;j--) sa[c[rk[tmp[j]]]--]=tmp[j];29 swap(rk,tmp);30 rk[sa[1]]=p=1;31 for(int j=2;j<=n;j++) rk[sa[j]]=cmp(tmp,sa[j],sa[j-1],i)?p:++p;32 if(p>=n) break;33 m=p;34 }35 }36 int main(){37 scanf("%s",s+1);38 n=strlen(s+1);39 Getsa();40 for(int i=1;i<=n;i++){41 outint(sa[i]);42 putchar(‘ ‘);43 }44 return 0;45 }
尾碼數組學習筆記