数据结构:后缀数组模板
2020-07-26 22:04
253 查看
/* Str :需要处理的字符串(长度为Len) Suffix[i] :Str下标为i ~ Len的连续子串(即后缀) Rank[i] : Suffix[i]在所有后缀中的排名 SA[i] : 满足Suffix[SA[1]] < Suffix[SA[2]] …… < Suffix[SA[Len]],即排名为i的后缀为Suffix[SA[i]] (与Rank是互逆运算) 最长公共前缀(Longest Common Prefix,LCP) Heigth[i] : 表示Suffix[SA[i]]和Suffix[SA[i - 1]]的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀 H[i] : 等于Height[Rank[i]],也就是后缀Suffix[i]和它前一名的后缀的最长公共前缀 而两个排名不相邻的最长公共前缀定义为排名在它们之间的Height的最小值。 */ const int N = 1e5+10; const int D = 18; int t1[N],t2[N],c[N],lg2[N]; struct suffix_array{ int str[N],sa[N],rank[N],height[N]; int rmq[D][N]; bool cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int n,int m){ n++; int i, j, p, *x = t1, *y = t2; for(i=0;i<m;++i) c[i]=0; for(i=0;i<n;++i) c[x[i]=str[i]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for(j=1;j<n;j<<=1){ p=0; for(i=n-j;i<n;++i) y[p++]=i; for(i=0;i<n;++i) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<m;++i) c[i]=0; for(i=0;i<n;++i) c[x[y[i]]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; for(i=1;i<n;++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; if(p>=n) break; m=p; } int k=0; n--; for(i=0;i<=n;++i) rank[sa[i]]=i; for(i=0;i<n;++i){ if(k) k--; j=sa[rank[i]-1]; while(str[i+k]==str[j+k]) ++k; height[rank[i]]=k; } } void initlcp(int n){ for(int i=1;i<=n;++i) rmq[0][i]=height[i]; for(int k=1;k<=lg2[n];++k)//做倍增 for(int i=1;i+(1<<k)-1<=n;++i) rmq[k][i]=min(rmq[k-1][i],rmq[k-1][i+(1<<(k-1))]); } int lcp(int a,int b){ a=rank[a]; b=rank[b]; if(a>b) swap(a,b); a+=1; int d=lg2[b-a+1]; return min(rmq[d][a],rmq[d][b-(1<<d)+1]); } }sa; char s[N]; int n; int p[N][3],f[3]; bool cmp(int a,int b){ for(int i=0,l,l1,l2;i<3;++i){ if(p[a][i]==n) return true; if(p[b][i]==n) return false; l1=p[a][i+1]-p[a][i]-1; l2=p[b][i+1]-p[b][i]-1; if(l1==0&&l2==0) continue; else if(l1==0) return true; else if(l2==0) return false; l=sa.lcp(p[a][i]+1,p[b][i]+1); if(l==min(l1,l2)){ if(l1==l2) continue; else return l1<l2; }else return sa.str[p[a][i]+1+l]<sa.str[p[b][i]+1+l]; } return false; } lg2[0]=-1; for(int i=1;i<N;++i) lg2[i]=(i&(i-1))?lg2[i-1]:lg2[i-1]+1;//预处理log
相关文章推荐
- 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现
- 数据结构之后缀数组suffix array
- 数据结构——前缀树 后缀树 后缀数组
- 数据结构之顺序栈(数组)C++(模板)
- 数据结构之后缀数组
- 数据结构之后缀数组(10)
- 数据结构之后缀数组
- 数据结构之后缀数组
- day05-MATLAB的数据类型--结构数组
- 数据结构之动态数组
- 数据结构与算法 - 数组
- 数据结构顺序表1(数组)
- 数据结构与算法:动态数组
- 重新温习数据结构一:数组
- poj 3294(经典后缀数组模板)
- 数据结构(1):使用面向对象模拟数组
- 后缀数组模板
- Java基础知识 初识Java 循环结构进阶 数组 数据类型 各种运算符
- 数据结构数组相关算法和螺旋,蛇形,拉丁矩阵的实现
- hdu 1403 Longest Common Substring (后缀数组模板题)