For each pre x of a given string S with N characters (each character
has an ASCII code between 97 and 126, inclusive), we want to know
whether the pre x is a periodic string. That is, for each i (2 i N
) we want to know the largest K > 1 (if there is one) such that the
pre x of S with length i can be written as A K , that is A
concatenated K times, for some string A . Of course, we also want to
know the period K . Input The input le consists of several test
cases. Each test case consists of two lines. The rst one contains N
(2 N 1000000) the size of the string S . The second line contains
the string S . The input le ends with a line, having the number zero
on it. Output For each test case, output ` Test case # ’ and the
consecutive test case number on a single line; then, for each pre x
with length i that has a period K > 1, output the pre x size i and the
period K separated by a single space; the pre x sizes must be in
increasing order. Print a blank line after each test case.
AC自动机模板题。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int ss=26;
int son[11010][30],last[11010],cnt[11010],fail[11010],num[160],n,tot,l[160],len,que[11010];
char s[160][80],str[1000010];
bool have[11010];
void init()
{
int i;
for (i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
l[i]=strlen(s[i]+1);
}
scanf("%s",str+1);
len=strlen(str+1);
memset(son,0,sizeof(son));
memset(fail,0,sizeof(fail));
memset(cnt,0,sizeof(cnt));
memset(have,0,sizeof(have));
memset(last,0,sizeof(last));
tot=0;
}
void build()
{
int i,j,p,hd,tl,u;
for (i=1;i<=n;i++)
{
p=0;
for (j=1;j<=l[i];j++)
{
if (!son[p][s[i][j]-'a']) son[p][s[i][j]-'a']=++tot;
p=son[p][s[i][j]-'a'];
}
num[i]=p;
have[p]=1;
}
hd=tl=1;
que[1]=0;
while (hd<=tl)
{
u=que[hd++];
if (have[fail[u]]) last[u]=fail[u];
else last[u]=last[fail[u]];
for (i=0;i<ss;i++)
if (son[u][i])
{
if (u) fail[son[u][i]]=son[fail[u]][i];
que[++tl]=son[u][i];
}
else son[u][i]=son[fail[u]][i];
}
}
void add(int p)
{
if (!p) return;
cnt[p]++;
add(last[p]);
}
void solve()
{
int i,p;
p=0;
for (i=1;i<=len;i++)
{
p=son[p][str[i]-'a'];
if (have[p]) add(p);
else add(last[p]);
}
}
void out()
{
int i,ans=0;
for (i=1;i<=n;i++)
ans=max(ans,cnt[num[i]]);
printf("%d\n",ans);
for (i=1;i<=n;i++)
if (cnt[num[i]]==ans) printf("%s\n",s[i]+1);
}
int main()
{
while (scanf("%d",&n)&&n)
{
init();
build();
solve();
out();
}
}