首页 > 代码库 > 【tyvj1860】后缀数组
【tyvj1860】后缀数组
描述
我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串。
后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较
定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0
你的任务就是求出SA和height这两个数组。字符串长度<=200000
后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])<suffix(sa[i+1]) 按照字典序方式比较
定义height[i]表示suffix(sa[i])与suffix(sa[i-1])之间的最长公共前缀长度,其中height[1]=0
你的任务就是求出SA和height这两个数组。字符串长度<=200000
输入格式
一行,为描述中的字符串(仅会出现小写字母)
输出格式
共两行,每行n个数,第一行为sa[i],第二行为height[i],其中每行的数均用空格隔开
测试样例1
输入
aabaaaab
输出
4 5 6 1 7 2 8 3
0 3 2 3 1 2 0 1
后缀数组模板题
随便贴一个写得很丑的模板
以后要把它背下来啊啊啊
QAQ
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 const int N=200050; 7 int Sa[N],wu[N],wv[N],wa[N],wb[N],R[N],Rank[N],Height[N],rank[N]; 8 char s[N]; 9 int cmp(int *r,int a,int b,int l){return r[a]==r[b] && r[a+l]==r[b+l];}10 inline void SA(int *r,int *sa,int n,int m){11 int *x=wa,*y=wb;12 for(int i=0;i<m;++i)wu[i]=0;13 for(int i=0;i<n;++i)++wu[x[i]=r[i]];14 for(int i=1;i<m;++i)wu[i]+=wu[i-1];15 for(int i=n-1;i>=0;--i)sa[--wu[x[i]]]=i;16 for(int j=1,p=0;p<n;j<<=1,m=p){17 p=0;18 for(int i=n-j;i<n;++i)y[p++]=i;19 for(int i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;20 for(int i=0;i<m;++i)wu[i]=0;21 for(int i=0;i<n;++i)++wu[wv[i]=x[y[i]]];22 for(int i=0;i<m;++i)wu[i]+=wu[i-1];23 for(int i=n-1;i>=0;--i)sa[--wu[wv[i]]]=y[i];24 swap(x,y);25 p=1;26 x[sa[0]]=0;27 for(int i=1;i<n;++i)x[sa[i]]=((y[sa[i]]==y[sa[i-1]]) && y[sa[i]+j]==y[sa[i-1]+j]) ? p-1 : p++;28 }29 }30 inline void Get_Height(int *r,int n){31 for(int i=1;i<=n;++i)rank[Sa[i]]=i;32 for(int i=0,j=0,k=0;i<n;Height[rank[i++]]=k)33 for(k?--k:0,j=Sa[rank[i]-1];r[i+k]==r[j+k];++k);34 }35 inline void output(int x){36 if(!x)return;output(x/10);37 putchar((x%10)+‘0‘);38 }39 int main(){40 scanf("%s",s);41 int len=strlen(s);42 for(int i=0;i<len;++i)R[i]=s[i]-‘a‘+1;43 R[len]=0;44 SA(R,Sa,len+1,30);45 Get_Height(R,len);46 for(int i=1;i<=len;++i)output(Sa[i]+1),putchar(‘ ‘);puts("");47 for(int i=1;i<=len;++i){48 if(!Height[i])putchar(‘0‘);49 else output(Height[i]);putchar(‘ ‘);50 }puts("");51 return 0;52 }
【tyvj1860】后缀数组
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。