[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2946
[算法]
建立多串后缀树
对于后缀树上的每个点 , 判断该节点所代表的等价类是否在所以字符串中出现 , 用该点的深度更新答案
时间复杂度 : O(NL)
[代码]
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int N = 1e5 + 10; const int ALPHA = 26; int n , ans; char s[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } struct Suffix_Automaton { int sz , last; int father[N] , child[N][ALPHA] , depth[N]; bool lab[N][6]; vector< int > a[N]; Suffix_Automaton() { sz = 1; last = 1; } inline int new_node(int dep) { depth[++sz] = dep; father[sz] = 0; memset(child[sz] , 0 , sizeof(child[sz])); memset(lab[sz] , 0 , sizeof(lab[sz])); return sz; } inline void extend(int ch , int c) { int np = child[last][ch]; if (np) { if (depth[np] == depth[last] + 1) { lab[np][c] = true; last = np; } else { int nq = new_node(depth[last] + 1); father[nq] = father[np]; father[np] = nq; memcpy(child[nq] , child[np] , sizeof(child[nq])); for (int p = last; child[p][ch] == np; p = father[p]) child[p][ch] = nq; lab[nq][c] = true; last = nq; } } else { int np = new_node(depth[last] + 1); int p = last; while (child[p][ch] == 0) { child[p][ch] = np; p = father[p]; } if (child[p][ch] == np) { father[np] = 1; lab[np][c] = true; last = np; return; } int q = child[p][ch]; if (depth[q] == depth[p] + 1) { father[np] = q; lab[np][c] = true; last = np; return; } else { int nq = new_node(depth[p] + 1); father[nq] = father[q]; father[np] = father[q] = nq; memcpy(child[nq] , child[q] , sizeof(child[q])); while (child[p][ch] == q) { child[p][ch] = nq; p = father[p]; } lab[np][c] = true; last = np; return; } } } inline void insert(char *s , int col) { last = 1; for (int i = 1; i <= strlen(s + 1); ++i) extend(s[i] - 'a' , col); } inline void dfs(int u) { for (unsigned i = 0; i < a[u].size(); ++i) { int v = a[u][i]; dfs(v); for (int j = 1; j <= n; ++j) lab[u][j] |= lab[v][j]; } bool all = true; for (int i = 1; i <= n; ++i) all &= lab[u][i]; if (all) chkmax(ans , depth[u]); } inline void work() { for (int i = 2; i <= sz; ++i) a[father[i]].push_back(i); dfs(1); } } SAM; int main() { read(n); for (int i = 1; i <= n; ++i) { scanf("%s" , s + 1); SAM.insert(s , i); } SAM.work(); printf("%d " , ans); return 0; }