借鉴然哥的 http://blog.csdn.net/zz_1215/article/details/8053262
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 200005;
const int maxc = 26;
const int inf = 1<<30;
int go[maxn][26];
int len[maxn];
int f[maxn];
int ma[maxn],mi[maxn];
bool vis[maxn];
class suffix_automaton
{
public:
const static int head = 1;
int last;
int use;
int get()
{
use++;
memset(go[use],0,sizeof(go[use]));
return use;
}
void init()
{
use=-1;
last=1;
get();
get();
f[0]=f[1]=len[0]=len[1]=0;
for(int i=0;i<maxn;++i) mi[i]=inf;
return;
}
void extend(int c)
{
int now =last;
int end = get();
len[end]=len[last]+1;
last=end;
for(;now&&!go[now][c];now=f[now])
{
go[now][c]=end;
}
if(!now)
{
f[end]=head;
}
else
{
int to = go[now][c];
if(len[now]+1==len[to])
{
f[end]=to;
}
else
{
int np = get();
memcpy(go[np],go[to],sizeof(go[to]));
len[np]=len[now]+1;
f[np]=f[to];
f[to]=f[end]=np;
for(;now&&go[now][c]==to;now=f[now])
{
go[now][c]=np;
}
}
}
}
void up(int now)
{
if(now==0||vis[now]) return;
else
{
ma[now]=len[now];
vis[now]=true;
up(f[now]);
}
}
void match(char *s)
{
for(int i=1;i<=use;++i)
{
ma[i]=0;
vis[i]=false;
}
int c;
int now = head;
int l =0;
for(int i=0;s[i];++i)
{
c = s[i]-'a';
if(go[now][c])
{
l++;
ma[now]=max(ma[now],l);
now = go[now][c];
up(f[now]);
}
else
{
while(now&&go[now][c]==0) now = f[now];
if(now==0)
{
l=0;
now = head;
}
else
{
l = len[now]+1;
now=go[now][c];
ma[now]=max(ma[now],l);
up(f[now]);
}
}
}
for(int i=1;i<=use;++i)
{
mi[i]=min(mi[i],ma[i]);
}
}
}SAM;
char a[maxn/2],b[maxn/2];
int main()
{
SAM.init();
scanf("%s",a);
for(int i=0;a[i];++i) SAM.extend(a[i]-'a');
while(scanf("%s",b)!=EOF)
{
SAM.match(b);
}
int ans=0;
for(int i=1;i<=SAM.use;++i)
ans=max(ans,mi[i]);
if(ans==inf) printf("0\n");
else printf("%d\n",ans);
return 0;
}