后缀数组模板
后缀数组是将某个字符串的所有后缀按照字典序排序后得到的数组,数组中存储的是字符串的起始下标。包括空串,所以如果字符串的长度为\(n\),则后缀数组中的元素个数为\(n+1\)
后缀数组的计算有基于倍增的时间复杂度为\(O(n\log ^2n)\)的算法,利用长度为\(k\)的排序结果对长度为\(2k\)的字符串排序
设\(rank_k(i)\)表示从下标\(i\)开始,长度为\(k\)的字符串在所有字符串中的字典序顺序
通过比较\(rank_k(i)\)与\(rank_k(j)\),\(rank_k(i+k)\)与\(rank_k(j+k)\),得到\(rank_{2k}(i)\)与\(rank_{2k}(j)\)的大小关系
const int maxn=400010;
int n,sa[maxn],rk[maxn],temp[maxn],rev[maxn],k;
bool cmp_sa(int i,int j){
if(rk[i]!=rk[j])return rk[i]<rk[j];
else{
int ri = i+k<=n?rk[i+k]:-1;
int rj = j+k<=n?rk[j+k]:-1;
return ri<rj;
}
}
void construct_sa(int *S,int len, int *sa){
int n=len;
for(k=1;k<=n;k*=2){
sort(sa,sa+n+1,cmp_sa);
temp[sa[0]]=0;
for(int i=1;i<=n;++i){
temp[sa[i]] = temp[sa[i-1]]+ (cmp_sa(sa[i-1],sa[i])?1:0);
}
for(int i=0;i<=n;++i){
rk[i]=temp[i];
}
}
}

浙公网安备 33010602011771号