Skip to content

Instantly share code, notes, and snippets.

@Chillee
Last active April 30, 2019 09:27
Show Gist options
  • Select an option

  • Save Chillee/71d27b77a0bb2036cecc18ff8d3b6d9c to your computer and use it in GitHub Desktop.

Select an option

Save Chillee/71d27b77a0bb2036cecc18ff8d3b6d9c to your computer and use it in GitHub Desktop.
Suffix Array
struct SuffixArray { // sa[0] = n, sa[i] = i-th in sorted suffix array. O(n log n)
#define rep(i, a, b) for (int i = a; i < (b); i++)
vector<int> sa, lcp;
SuffixArray(string &s, int lim = 256) { // no null characters, use basic_string<int> to extend
int n = s.size() + 1, k = 0, a, b;
vector<int> x(all(s) + 1), y(n), ws(max(n, lim)), rank(n);
sa = lcp = y, iota(all(sa), 0);
for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) {
p = j, iota(all(y), n - j);
rep(i, 0, n) if (sa[i] >= j) y[p++] = sa[i] - j;
fill(all(ws), 0);
rep(i, 0, n) ws[x[i]]++;
partial_sum(all(ws), begin(ws));
for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i];
swap(x, y), p = 1, x[sa[0]] = 0;
rep(i, 1, n) a = sa[i - 1], b = sa[i], x[b] = (y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++;
} // lcp[0] = 0, lcp[i] = lcp(sa[i], sa[i-1])
rep(i, 1, n) rank[sa[i]] = i;
for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k)
for (k &&k--, j = sa[rank[i] - 1]; s[i + k] == s[j + k]; k++);
}
#undef rep
};
@Chillee
Copy link
Author

Chillee commented Apr 14, 2019

Runs in about 1.2 seconds for N=5e6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment