利用后缀数组和尺取法求得相邻两个后缀数组之间的最长公共前缀,计入lcp数组,这个数组就是高度数组。求整个串从i到j的最长公共前缀就是一个高度数组上的标准的RMQ问题。
int rank[maxn];
void calc_lcp(char*s, int *sa, int *lcp) {
int n = strlen(s);
for (int i = 0; i <= n; i++) rank[sa[i]] = i;
int h;
lcp[0] = 0;
for (int i = 0; i < n; i++) {
int j = sa[rank[i] - 1];
if (h > 0) h--;//i时,前面有h个公共前缀,则i+1时,一定不小于h-1个
for (; j + h < n&&i + h < n; h++) {
if (s[j + h] != s[i + h]) break;
}
lcp[rank[i] - 1] = h;
}
}