题目链接
后缀数组模板题。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, c[N], sa[N];
int rank[N], height[N];
char str[N];
inline void buildSa(int m) {
int *x = rank, *y = height;
for (int i = 0; i < m; i++) c[i] = 0;
for (int i = 0; i < n; i++) c[x[i] = str[i]]++;
for (int i = 1; i < m; i++) c[i] += c[i - 1];
for (int i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for (int k = 1; k <= n; k <<= 1) {
int p = 0;
for (int i = n - k; i < n; i++) y[p++] = i;
for (int i = 0; i < n; i++) if (sa[i] >= k) y[p++] = sa[i] - k;
for (int i = 0; i < m; i++) c[i] = 0;
for (int i = 0; i < n; i++) c[x[y[i]]]++;
for (int i = 1; i < m; i++) c[i] += c[i - 1];
for (int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y); x[sa[0]] = 0; p = 1;
for (int i = 1; i < n; i++)
x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p - 1 : p++;//这里有点担心越界
if (p >= n) break;
m = p;
}
}
inline void calcHeight() {
int k = 0;
for (int i = 0; i < n; i++) rank[sa[i]] = i;
for (int i = 0; i < n - 1; i++) {
if (k) k--;
int j = sa[rank[i] - 1];
while (str[i + k] == str[j + k]) k++;
height[rank[i]] = k;
}
}
int main() {
scanf("%s", str);
n = strlen(str);
for (int i = 0; i < n; i++)
str[i] -= 'a' - 1;
str[n++] = 0;//补$不能省略
buildSa(30);
calcHeight();
for (int i = 1; i < n; i++)
printf("%d ", sa[i] + 1); puts("");
for (int i = 2; i < n; i++)
printf("%d ", height[i]); puts("");
return 0;
}