后缀数组学习笔记

Posted halfrot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后缀数组学习笔记相关的知识,希望对你有一定的参考价值。

现在来看倍增算法是非常好理解的。

直接放一篇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 }

 

以上是关于后缀数组学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

[后缀数组]学习笔记未完

后缀树组 学习笔记

学习笔记:python3,代码片段(2017)

PHP 学习笔记:基础教程:语法,变量,函数,数组,超全局

DOM探索之基础详解——学习笔记

●后缀数组○十三个例题