后缀数组的倍增算法模板

代码摘自2009年国家集训队论文

 1 #include<iostream>
 2 #define ws gzh
 3 //ws是库中定义过的名称,有些编译器无法通过
 4 using namespace std;
 5 const int maxn=1024;
 6 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
 7 int cmp(int *r,int a,int b,int l)
 8 {return r[a]==r[b]&&r[a+l]==r[b+l];}
 9 void da(int *r,int *sa,int n,int m)
10 {
11     //倍增算法
12     int i,j,p,*x=wa,*y=wb,*t;
13     for(i=0;i<m;i++) ws[i]=0;
14     for(i=0;i<n;i++) ws[x[i]=r[i]]++;
15     for(i=1;i<m;i++) ws[i]+=ws[i-1];
16     for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
17     for(j=1,p=1;p<n;j*=2,m=p)
18     {
19         for(p=0,i=n-j;i<n;i++) y[p++]=i;
20         for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
21         for(i=0;i<n;i++) wv[i]=x[y[i]];
22         for(i=0;i<m;i++) ws[i]=0;
23         for(i=0;i<n;i++) ws[wv[i]]++;
24         for(i=1;i<m;i++) ws[i]+=ws[i-1];
25         for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
26         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
27         x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
28     }
29     return;
30 }
31 int main()
32 {
33     return 0;
34 }
时间: 2024-11-13 18:19:09

后缀数组的倍增算法模板的相关文章

后缀数组之倍增算法

首先说明 :后缀数组的构建在网上有多种方法:朴素的n*n*logn,还有倍增n*logn的,还有3*n的DC3算法,当然还有DC算法.这个算法学习自林厚丛老师的<高级数据结构>,代码较长,而且常数也比较大,但是是我这种笨人可以理解的.如有人想学短而快的可以学习<罗穗骞 后缀数组 ---处理字符串的有力工具>.顺便说一下,罗大神的算法书写的的确很短小也漂亮,可惜我看不懂. 说一下学习的心路历程吧!最开始想学后缀树,道理看明的了,可是一看代码实在是太长了(可能是我找的模版不对吧).后来

后缀数组:倍增法和DC3的简单理解

一些定义:设字符串S的长度为n,S[0~n-1]. 子串:设0<=i<=j<=n-1,那么由S的第i到第j个字符组成的串为它的子串S[i,j]. 后缀:设0<=i<=n-1,那么子串S[i,n-1]称作它的后缀,用Suffix[i]表示. 串比较:对于两个串S1,S2,设长度分别为n1,n2.若存在一个位置i,使得对于0<=j<i满足S1[j]=S2[j]且S1[i]<S2[i],那么我们称S1<S2.如果S1是S2的一个前缀,那么也有S1<S2

后缀数组-倍增算法模板

void build_sa(int m) { int *x = t, *y = t2; for(int i = 0; i < m; i ++) c[i] = 0; for(int i = 0; i < n; i ++) c[x[i]=s[i]] ++; for(int i = 1; i < m; i ++) c[i] += c[i-1]; for(int i = n-1; i >= 0; i --) sa[--c[x[i]]] = i; for(int k = 1; k <=

●后缀数组○十三个例题

●之前学习过后缀数组的倍增算法,但也只是简单练了练倍增(O(n ㏒ n)). ●如今再次开始后缀,借助罗穗骞的论文<后缀数组--处理字符串的有力工具>,练习了论文里那十三个例题,学习了里面所包含的后缀数组处理字符串的应用. ●感觉收获不少,后缀倍增+后缀应用的代码能力提高了不少. ●于此发上各题方法的小总结和以及的AC代码 ●后缀数组的应用 ●一个字符串 ○求字符串的字串个数.(spoj694 spoj705) 方法:一个串中不同子串的总数=∑(len-height[i]-sa[i])

后缀数组模板及解释

以前做过后缀数组,直接用模板,最近打算重新认真的学一遍.感觉学一个东西一定要弄懂了,不然到最后还是要重学. int wa[MAXN],wb[MAXN],wv[MAXN],Ws[MAXN]; void da(int *r,int *sa,int n,int m){//n表示字符串长度 + 1,包括添加的那个0,m表示取值的范围 //把单个字符进行基数排序 int *x = wa,*y = wb; for(int i = 0; i < m; i++)Ws[i] = 0; for(int i = 0;

【后缀数组】【真难懂啊】

基本上一搜后缀数组网上的模板都是<后缀数组——处理字符串的有力工具>这一篇的注释,O(nlogn)的复杂度确实很强大,但对于初次接触(比如窝)的人来说理解起来也着实有些困难(比如窝就活活好了两天的光阴..),看了那么多材料感觉<挑战程序设计>的后缀数组解释理解起来会相对容易很多,然而它的复杂度是O(nlog2n)的,主要区别是对子串排序的时候前者用了基数排序--O(n),而后者用了快排--O(nlogn),这就导致了最终的复杂度后者比前者多了一个O(logn). 先整理下<挑

后缀数组,集各家之大成

作用有待更新.... 大佬博客:https://www.cnblogs.com/jinkun113/p/4743694.html: https://www.luogu.com.cn/problemnew/solution/P3809: 后缀数组: 复杂度:N(NlogN) 理论原理加模板: 后缀数组使用倍增法这里不加以叙述+桶排序: 先来了解一下桶排序,要拍一个1-99的数,我们先按照各位放到十个桶里,然后按照顺序取出来放到十位的桶里,这样我们在保证十位相同的时候个位小的先被放入桶里,所以答案的

[bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列SA[1],SA[2],……,SA[n],并且保证Suffix(SA[i])<Suffix(SA[i+1]),1≤i<n. 也就是将S的n个后缀从小到大进行排序之后把排好序的后缀的开头位置顺次放入SA中. height数组:定义height[i]=suffix(sa[i-1])和suffix(sa[

利用后缀数组(suffix array)求最长公共子串(longest common substring)

摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其重要的优势在于可以编码简单,代码易于理解,适合快速实现. 首先,来说明一下,LCS通常指的是公共最长子序列(Longest Common Subsequence,名称来源参见<算法导论>原书第3版p223),而不是公共最长子串(也称为最长公共子串). 最长公共子串问题是在文本串.模式串中寻找共有的