uva1449 Dominating Patterns

来源:互联网 发布:软件项目生命周期模型 编辑:程序博客网 时间:2024/06/07 21:50

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();    }}
0 0
原创粉丝点击