【后缀数组】uoj#35. 后缀排序
2015-04-26 17:29
369 查看
模板
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 100001 int sa ,t ,t2 ,tong ,n; char s ; inline bool cmp(int *y,int i,int k) { return (y[sa[i-1]]==y[sa[i]])&&((sa[i-1]+k>=n?-1:y[sa[i-1]+k])==(sa[i]+k>=n?-1:y[sa[i]+k])); } //构造字符串s的后缀数组,每个字符值必须为0~m-1,字符串下标为0~n-1 void build_sa(int range) { int *x=t,*y=t2; //基数排序 memset(tong,0,sizeof(int)*range);//清空桶 for(int i=0;i<n;++i) tong[x[i]=s[i]]++;//把s拷贝到x中,之后插入桶 for(int i=1;i<range;++i) tong[i]+=tong[i-1];//将桶处理成前缀和 for(int i=n-1;i>=0;--i) sa[--tong[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; //直接利用sa数组排序第二关键字 for(int i=n-k;i<n;++i) y[p++]=i; for(int i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k; //基数排序第一关键字 memset(tong,0,sizeof(int)*range); for(int i=0;i<n;++i) tong[x[y[i]]]++; for(int i=0;i<range;++i) tong[i]+=tong[i-1]; for(int i=n-1;i>=0;--i) sa[--tong[x[y[i]]]]=y[i]; //根据sa和y数组计算新的x数组 swap(x,y); p=1; x[sa[0]]=0; for(int i=1;i<n;++i) x[sa[i]]= cmp(y,i,k) ? p-1 : p++; if(p>=n) break; range=p; } } int rank ,lcp ; void get_lcp() { int k=0; for(int i=0;i<n;++i) rank[sa[i]]=i; for(int i=0;i<n;++i) if(rank[i]) { if(k) --k; int j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) ++k; lcp[rank[i]]=k; } } int main() { scanf("%s",s); n=strlen(s); build_sa('z'+1); for(int i=0;i<n;++i) printf("%d ",sa[i]+1); puts(""); if(n>1) get_lcp(); for(int i=1;i<n;++i) printf("%d ",lcp[i]); return 0; }
相关文章推荐
- Uoj #35. 后缀排序(后缀数组)
- UOJ #35. 后缀排序(后缀数组模板题)
- UOJ #35. 后缀排序[后缀数组详细整理]
- UOJ #35. 后缀排序 后缀数组模板题
- 字符串排序及后缀数组实现
- [省选前题目整理][UOJ 35]后缀排序(后缀数组)
- 【UOJ #35】后缀排序 后缀数组模板
- 【后缀数组】后缀排序
- uoj#35. 后缀排序 后缀数组
- luogu #3809 【模板】后缀排序(后缀数组)
- 关于网上搜查得到的3DC3的基于字符串后缀数组的排序方法的怀疑
- 【后缀数组】后缀排序
- 后缀数组基数排序——bzoj3172: [Tjoi2013]单词
- Uoj#35. 后缀排序
- 后缀子串排序(后缀数组) - 上海交通大学计算机历年考研复试上机题
- uoj #35. 后缀排序
- 【UOJ 35】 后缀排序|后缀数组 *2
- uoj#35 后缀排序(后缀数组模版)
- 洛谷.3809.[模板]后缀排序(后缀数组 倍增)
- 【UOJ 35】 后缀排序|后缀数组 *3