后缀数组
Posted vscoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了后缀数组相关的知识,希望对你有一定的参考价值。
#include<cstdio> #include<cstring> #include<algorithm> const int maxn=555555; int n,m; char s[maxn]; int sa[maxn],tp[maxn]; int rank[maxn],tong[maxn]; void qsort() { for(int i=0;i<=m;i++) tong[i]=0; for(int i=1;i<=n;i++) tong[rank[i]]++; for(int i=0;i<=m;i++) tong[i]+=tong[i-1]; for(int i=n;i>=1;i--) sa[tong[rank[tp[i]]]--]=tp[i]; } void get_sa() { m=127; for(int i=1;i<=n;i++) { rank[i]=s[i]; tp[i]=i; } qsort(); for(int w=1,p;p<n;m=p,w<<=1) { p=0; for(int i=1;i<=w;i++) tp[++p]=n-w+i; for(int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w; qsort(); std::swap(rank,tp); rank[sa[1]]=p=1; for(int i=2;i<=n;i++) rank[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p; } } int rak[maxn]; int height[maxn]; void get_he() { int k=0; for(int i=1;i<=n;i++) rak[sa[i]]=i; for(int i=1;i<=n;i++) { if(rak[i]==1) continue; if(k) k--; int j=sa[rak[i]-1]; while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++; height[rak[i]]=k; } } int lg[maxn]; int st[maxn][22]; void build_st() { lg[1]=0; for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1; for(int i=1;i<=n;i++) st[i][0]=height[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;(i+(1<<j)-1)<=n;i++) st[i][j]=std::min(st[i][j-1],st[i+(1<<(j-1))][j-1]); } void pre_solve() { get_sa(); get_he(); build_st(); } int get_lcp(int a,int b) { a=rak[a],b=rak[b]; if(a>b) std::swap(a,b); a++; int k=lg[b-a+1]; return std::min(st[a][k],st[b-(1<<k)+1][k]); } int main() { }
以上是关于后缀数组的主要内容,如果未能解决你的问题,请参考以下文章