题目链接
先占个坑,以后再补。
(SA)的总结肯定是要写的。
等理解地深入一点再补。
#include <cstdio>
#include <cstring>
const int MAXN = 1000010;
int sa[MAXN], x[MAXN], c[MAXN], y[MAXN], n, m = 122;
char s[MAXN];
int main(){
scanf("%s", s + 1);
n = strlen(s + 1);
for(int i = 1; i <= n; ++i) ++c[x[i] = s[i]];
for(int i = 2; i <= m; ++i) c[i] += c[i - 1];
for(int i = n; i; --i) sa[c[x[i]]--] = i;
for(int k = 1; k <= n; k <<= 1){
int num = 0;
for(int i = n - k + 1; i <= n; ++i) y[++num] = i;
for(int i = 1; i <= n; ++i) if(sa[i] > k) y[++num] = sa[i] - k;
for(int i = 1; i <= m; ++i) c[i] = 0;
for(int i = 1; i <= n; ++i) ++c[x[i]];
for(int i = 2; i <= m; ++i) c[i] += c[i - 1];
for(int i = n; i; --i) sa[c[x[y[i]]]--] = y[i];
memcpy(y, x, sizeof x);
x[sa[1]] = 1; num = 1;
for(int i = 2; i <= n; ++i)
x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? num : ++num;
if(num == n) break;
m = num;
}
for(int i = 1; i <= n; ++i)
printf("%d ", sa[i]);
return 0;
}