码迷,mamicode.com
首页 > 编程语言 > 详细

后缀数组学习笔记

时间:2017-09-04 19:57:18      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:后缀数组   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 }

 

后缀数组学习笔记

标签:后缀数组   string   out   模板   www   span   algorithm   namespace   www.   

原文地址:http://www.cnblogs.com/halfrot/p/7474979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!