Description
A string is finite sequence of characters over a non-empty finite set Σ.
In this problem, Σ is the set of lowercase letters.
Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.
Now your task is a bit harder, for some given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Input: alsdfkjfjkdsal fdjskalajfkdsla aaaajfaaaa Output: 2
Notice: new testcases added
后缀自动机
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn = 300005; char s[maxn]; class SAM { const static int maxn = 500005; //节点个数 const static int size = 26; //字符的范围 const static char base = 'a'; //字符的基准 class node { public: node *fa, *next[size]; int len, cnt[10]; node* clear(int x) { fa = 0; len = x; memset(cnt, 0, sizeof(cnt)); memset(next, 0, sizeof(next)); return this; } }nd[maxn]; //节点的设置 node *root, *last; //根节点,上一个节点 int tot; //总节点数 public: void clear() { last = root = &nd[tot = 0]; nd[0].clear(0); } //初始化 void insert(char ch) { node *p = last, *np = nd[++tot].clear(p->len + 1); last = np; int x = ch - base; while (p&&p->next[x] == 0) p->next[x] = np, p = p->fa; if (p == 0) { np->fa = root; return; } node* q = p->next[x]; if (p->len + 1 == q->len) { np->fa = q; return; } node *nq = nd[++tot].clear(p->len + 1); for (int i = 0; i < size; i++) if (q->next[i]) nq->next[i] = q->next[i]; nq->fa = q->fa; q->fa = np->fa = nq; while (p &&p->next[x] == q) p->next[x] = nq, p = p->fa; } //插入操作 void find(char *ch, int y) { node *s = root; int maxlen = 0; for (int i = 0; ch[i]; i++) { int x = ch[i] - base; if (s->next[x]) { s = s->next[x]; s->cnt[y] = max(s->cnt[y], ++maxlen); } else { while (s&&!s->next[x]) { s->cnt[y] = max(s->cnt[y], maxlen); s = s->fa; } if (s == 0) s = root,maxlen = 0; else { maxlen = s->len + 1; s = s->next[x]; s->cnt[y] = max(s->cnt[y], maxlen); } } } } void query(int x) { int ans = 0; for (int i = tot; i; i--) { int u = nd[i].len; for (int j = 0; j < x; j++) u = min(u, nd[i].cnt[j]); ans = max(ans, u); } printf("%d\n", ans); } }sam; int main() { scanf("%s", s); sam.clear(); for (int i = 0; s[i]; i++) sam.insert(s[i]); int j; for (j = 0; ~scanf("%s", s); j++) sam.find(s, j); sam.query(j); return 0; }