【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 20005 #define MAXM 10 #define CSIZE 26 template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } struct Suffix_Automaton { int child[MAXN][CSIZE]; int father[MAXN], depth[MAXN]; int root, size, last, n, ans; vector <int> a[MAXN]; bool visited[MAXN][MAXM]; int new_node(int dep) { father[size] = 0; depth[size] = dep; memset(child[size], 0, sizeof(child[size])); return size++; } void init(int x) { n = x; size = 0; root = last = new_node(0); } void Extend(int ch, int type) { int p = last, np = child[p][ch]; if (np == 0) { np = new_node(depth[p] + 1); while (child[p][ch] == 0) { child[p][ch] = np; p = father[p]; } if (child[p][ch] == np) father[np] = root; else { int q = child[p][ch]; if (depth[q] == depth[p] + 1) father[np] = q; else { int nq = new_node(depth[p] + 1); father[nq] = father[q]; father[q] = father[np] = nq; memcpy(child[nq], child[q], sizeof(child[q])); while (child[p][ch] == q) { child[p][ch] = nq; p = father[p]; } } } } else if (depth[np] != depth[p] + 1) { np = new_node(depth[p] + 1); int tmp = child[p][ch]; father[np] = father[tmp]; father[tmp] = np; memcpy(child[np], child[tmp], sizeof(child[tmp])); while (child[p][ch] == tmp) { child[p][ch] = np; p = father[p]; } } last = np; visited[np][type] = true; } void insert(char *s, int type) { int len = strlen(s + 1); last = root; for (int i = 1; i <= len; i++) Extend(s[i] - 'a', type); } void work(int root) { for (unsigned i = 0; i < a[root].size(); i++) { work(a[root][i]); for (int j = 1; j <= n; j++) visited[root][j] |= visited[a[root][i]][j]; } bool valid = true; for (int i = 1; i <= n; i++) valid &= visited[root][i]; if (valid) ans = max(ans, depth[root]); } int query() { for (int i = 1; i <= size; i++) a[father[i]].push_back(i); ans = 0; work(0); return ans; } } SAM; char s[MAXN]; int main() { int n; read(n); SAM.init(n); for (int i = 1; i <= n; i++) { scanf("\n%s", s + 1); SAM.insert(s, i); } cout << SAM.query() << endl; return 0; }