http://deque.tistory.com/82
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 1000000;
int sa[MAX], temp[MAX], pos[MAX], N, delta, lcp[MAX];
char S[MAX];
bool cmp(int i, int j) {
if (pos[i] != pos[j]) return pos[i] < pos[j];
i += delta;
j += delta;
return (i < N && j < N) ? (pos[i] < pos[j]) : (i > j);
}
int main() {
scanf("%s", S);
N = strlen(S);
for (int i = 0; i < N; i++) {
sa[i] = i;
pos[i] = S[i] - 'a';
temp[i] = 0;
}
for (delta = 1; ; delta *= 2) {
sort(sa, sa + N, cmp);
for (int i = 1; i < N; i++) {
temp[i] = temp[i - 1] + cmp(sa[i - 1], sa[i]);
}
for (int i = 0; i < N; i++) {
pos[sa[i]] = temp[i];
}
if (temp[N - 1] == N - 1) break;
memset(temp, 0, sizeof(temp));
}
for (int i = 0; i < N; i++) printf("%d ", sa[i] + 1);
printf("\n");
int sameCount = 0;
for (int i = 0; i < N; i++) {
if (sameCount > 0) sameCount--;
if (sameCount < 0) sameCount = 0;
if (pos[i] == 0) continue;
int firstIndex = i;
int nextIndex = sa[pos[firstIndex] - 1];
while (true) {
if (((firstIndex + sameCount) >= N) || ((nextIndex + sameCount) >= N)) break;
if (S[firstIndex + sameCount] == S[nextIndex + sameCount]) sameCount++;
else break;
}
lcp[pos[i]] = sameCount;
}
printf("x ");
for (int i = 1; i < N; i++) printf("%d ", lcp[i]);
return 0;
}