#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <iostream>
// #include <ctime>
// #include <cmath>
// #include <map>
// #include <vector>
// #include <set>
#include <string>
#define open_in(x) freopen(""#x".in","r",stdin)
#define open_out(x) freopen(""#x".out","w",stdout)
#define open_(x) freopen(""#x".in","w",stdout)
#define open(x) open_in(x); open_out(x)
#define mes(x, y) memset(x, y, sizeof(x))
#define mec(x, y) memcpy(x, y, sizeof(x))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int X = 200010;
const int M = 1e9+7;
// inline int Random(int a,int b) {return rand() % (b - a + 1) + a;}
template<class T>
inline T read(T &x) {
int f = 1;char ch = getchar();x = 0;
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x *= f;
}
int n, m, sa[X], rak[X], tmp[X], buk[X], height[X];
string str;
// int ans = 0;
void Sort() {
for (int i = 1; i <= m; i++) buk[i] = 0;
for (int i = 1; i <= n; i++) buk[rak[i]]++;
for (int i = 1; i <= m; i++) buk[i] += buk[i - 1];
for (int i = n; i >= 1; i--) sa[buk[rak[tmp[i]]]--] = tmp[i];
}
int main() {
open_in(SA);
read(n);
cin >> str;
str = ' ' + str;
for (int i = 1; i <= n; i++) {
m = max(m, rak[i] = str[i] - 'a' + 1);
tmp[i] = i;
}
Sort();
for (int p = 0, k = 1; p < n; k <<= 1, m = p) {
p = 0;
for (int i = 1; i <= k; i++) tmp[++p] = n - k + i;
for (int i = 1; i <= n; i++)
if (sa[i] > k)
tmp[++p] = sa[i] - k;
Sort();
swap(rak, tmp);
rak[sa[1]] = p = 1;
for (int i = 2; i <= n; i++)
rak[sa[i]] = (tmp[sa[i]] == tmp[sa[i-1]] && tmp[sa[i] + k] == tmp[sa[i - 1] + k] ? p : ++p);
}
for (int i = 1, Max = 0; i <= n; i++) {
Max = max(Max - 1, 0);
while (str[i + Max] == str[sa[rak[i] - 1] + Max]) Max++;
height[rak[i]] = Max;
}
/*for (int i = 1; i <= n; i++)
ans = max(ans, height[rak[i]]);
printf("%d\n", ans);*/
return 0;
}
来源:https://blog.csdn.net/weixin_43993341/article/details/99230399