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.
Input
The input contains at most 10 lines, each line consists of no more than 100000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
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;
}