Spoj 1812 Lcs2-longest Common Substring II
Test instructions
Give up to n strings a[1], ..., a[n], to find the longest common substring of the n string.
Limit:
1 <= N <= 10
| a[i]| <= 1e5
Ideas:
The same approach as SPOJ 1811 LCS
Put one of the a suffix automata
Consider a state s, if a string other than a match length of it is a[1], a[2], ..., a[n-1], then min (a[1], a[2], ..., a[n-1], Max (s) can update the answer.
Attention:
We are asking for the maximum matching length of R in any right set. Then for a state s, the result of it can naturally be as the result of its parent, we can update it from bottom to top.
This can be done by a topological sort.
/*spoj 1812 lcs2-longest Common Substring II test instructions: gives up to n strings a[1], ..., a[n], to find the longest common substring of the n string. Limit: 1 <= n <= 10 | a[i]| <= 1e5 idea: and Spoj 1811 LCS similar to the practice of putting one of the A-suffix automata to consider a state s, if a string other than the matching length of it is a[1], a[2], then min (a[n-1], a[1 ], ..., a[n-1], Max (s) can update the answer. Note: We are asking for the maximum matching length of R in any right set. Then for a state s, the result of it can naturally be as the result of its parent, we can update it from bottom to top. This can be done by a topological sort. */#include <iostream> #include <cstdio> #include <cstring>using namespace std;const int N = 1e5 + 5;char s Tr[15][n];int maxx[2 * N], minn[2 * n];struct SAM {struct Node {int fa, ch[27];int val;void init () {fa = val = 0;memset (ch , 0, sizeof (CH));}} node[2 * n];int tot;int New_node () {node[++tot].init (); return tot;} int root, last;void init () {root = last = Tot = 1;node[0].init (); Node[1].init ();} void Add (int x) {int p = last;int np = New_node (); node[np].val = Node[p].val + 1;while (P && node[p].ch[x] = = 0) { Node[p].ch[x] = Np;p = NODE[P].FA;} if (p = = 0) Node[np].fa = root;else {int q = node[P].ch[x];if (node[p].val + 1 = = node[q].val) Node[np].fa = q;else {int NQ = New_node (); node[nq].val = Node[p].val + 1;MEMCP Y (node[nq].ch, node[q].ch, sizeof (node[q].ch)), Node[nq].fa = Node[q].fa;node[q].fa = Node[np].fa = Nq;while (P & & Node[p].ch[x] = = q) {Node[p].ch[x] = Nq;p = Node[p].fa;}}} last = NP;} void Debug () {for (int i = 1; I <= tot; ++i) {printf ("id=%d, fa=%d, step=%d, ch=[", I, Node[i].fa, node[i].val); for (int j = 0; J < 26; ++J) {if (Node[i].ch[j]) printf ("%c,%d", j+ ' a ', Node[i].ch[j]);} Puts ("]");}} void Gao (int);} Sam;int du[2 * N];int que[2 * n], FR, Ta;int b[2 * n], b_tot;void Sam::gao (int N) {init (); int len1 = strlen (str[0]); t i = 0; i < len1; ++i) Add (str[0][i]-' a ');//debug (); b_tot = fr = TA = 0;for (int i = 1; I <= tot; ++i) ++du[node[i].fa];for (int i = 1; I & Lt;= tot; ++i) if (du[i] = 0) que[ta++] = i, b[b_tot++] = I;while (fr! = ta) {int u = que[fr++];int v = node[u].fa;--du[v];if (du[v] = = 0) que[ta++] = V, b[b_tot++] = V;} for (int i = 1; I <=Tot ++i) Minn[i] = node[i].val;for (int i = 1; i < n; ++i) {int len = strlen (str[i]); int p = root;int tmp = 0;fill (Maxx, Maxx + tot + 1, 0); for (int j = 0; j < Len; ++j) {int x = str[i][j]-' a '; if (Node[p].ch[x]) {++tmp;p = node[p].ch[x];} else {while (P && node[p].ch[x] = = 0) p = node[p].fa;if (p) {tmp = Node[p].val + 1;p = node[p].ch[x];} else {p = root;tmp = 0;}} MAXX[P] = max (maxx[p], tmp);} for (int j = 0; j < tot; ++j) {int u = b[j];minn[u] = min (Minn[u], maxx[u]); int v = node[u].fa;maxx[v] = max (Maxx[v], MA Xx[u]);}} int ans = 0;for (int i = 1; I <= tot; ++i) ans = max (ans, minn[i]);p rintf ("%d\n", ans);} int main () {int n = 0;while (scanf ("%s", Str[n])! = EOF) ++n;sam.gao (n); return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Spoj 1812 Lcs2-longest Common Substring II (suffix automaton)