写在前面
学了5,6遍,学一次忘一次 所以还是整理一下吧
定义
一个rk数组 一个sa数组
rk[i]表示第i个后缀的排名
sa[i]表示排名为i的后缀的初始位置的下标
Code
#include<bits/stdc++.h>
using namespace std;
#define rint register int
const int maxn = 1e6 + 10;
int rk[maxn],tp[maxn],sa[maxn],cnt[maxn],n,m;
char s[maxn];
void Rsort() {
memset(cnt+1,0,m*4);
for(rint i = 1;i <= n;++i) cnt[rk[i]]++;
for(rint i = 2;i <= m;++i) cnt[i] += cnt[i-1];
for(rint i = n;i >= 1;--i) sa[cnt[rk[tp[i]]]--] = tp[i];
}
int main(){
scanf("%s",s+1);
n = strlen(s+1), m = 75;
for(rint i = 1;i <= n;++i) rk[i] = s[i] - '0' + 1, tp[i] = i;
Rsort();
for(rint w = 1, p = 0;p < n;m = p, w *= 2) {
p = 0;
for(rint i = n-w+1;i <= n;++i) tp[++p] = i;
for(rint i = 1;i <= n;++i) if(sa[i] > w) tp[++p] = sa[i] - w;
Rsort(); memcpy(tp+1,rk+1,n*4); p = rk[sa[1]] = 1;
for(rint i = 2;i <= n;++i) rk[sa[i]] = (tp[sa[i]]==tp[sa[i-1]] && tp[sa[i]+w]==tp[sa[i-1]+w]) ? p : ++p;
}
for(rint i = 1;i <= n;++i) printf("%d ",sa[i]);
return 0;
}