int n, a[MAXN], sa[MAXN], rk[MAXN], ht[MAXN], st[MAXN][MAXLOGN + 1];
inline void suffixArray() {
static int set[MAXN];
std::copy(a, a + n, set);
std::sort(set, set + n);
int *end = std::unique(set, set + n);
for (int i = 0; i < n; i++) a[i] = std::lower_bound(set, end, a[i]) - set;
static int fir[MAXN], sec[MAXN], tmp[MAXN], _buc[MAXN + 1], *buc = _buc + 1;
for (int i = 0; i < n; i++) buc[a[i]]++;
for (int i = 0; i < n; i++) buc[i] += buc[i - 1];
for (int i = 0; i < n; i++) rk[i] = buc[a[i] - 1];
for (int t = 1; t < n; t <<= 1) {
for (int i = 0; i < n; i++) fir[i] = rk[i];
for (int i = 0; i < n; i++) sec[i] = (i + t >= n) ? -1 : fir[i + t];
std::fill(buc - 1, buc + n, 0);
for (int i = 0; i < n; i++) buc[sec[i]]++;
for (int i = 0; i < n; i++) buc[i] += buc[i - 1];
for (int i = 0; i < n; i++) tmp[n - buc[sec[i]]--] = i;
std::fill(buc - 1, buc + n, 0);
for (int i = 0; i < n; i++) buc[fir[i]]++;
for (int i = 0; i < n; i++) buc[i] += buc[i - 1];
for (int j = 0, i; j < n; j++) i = tmp[j], sa[--buc[fir[i]]] = i;
for (int j = 0, i, last = -1; j < n; j++) {
i = sa[j];
if (last == -1) rk[i] = 0;
else if (fir[i] == fir[last] && sec[i] == sec[last]) rk[i] = rk[last];
else rk[i] = rk[last] + 1;
last = i;
}
}
for (int i = 0, k = 0; i < n; i++) {
if (rk[i] == 0) k = 0;
else {
if (k > 0) k--;
int j = sa[rk[i] - 1];
while (i + k < n && j + k < n && a[i + k] == a[j + k]) k++;
}
ht[rk[i]] = k;
}
}
后缀数组
最新推荐文章于 2023-04-10 11:25:04 发布
本文详细介绍了一种构造Suffix Array的有效算法,通过使用桶排序和计数排序等技术来优化排序过程,实现了线性时间复杂度的Suffix Array构建。此外,还讨论了如何计算不同后缀间的最长公共前缀。
摘要由CSDN通过智能技术生成