• 模板 AC自动机


    题目描述

    有$N$ 个由小写字母组成的模式串以及一个文本串$T$ 。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串$T$ 中出现的次数最多。

    输入输出格式

    输入格式:

    输入含多组数据。

    每组数据的第一行为一个正整数$N$ ,表示共有$N$ 个模式串,$1 leq N leq 150$ 。

    接下去$N$ 行,每行一个长度小于等于$70$ 的模式串。下一行是一个长度小于等于$10^6$ 的文本串$T$ 。

    输入结束标志为$N=0$ 。

    输出格式:

    对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。

    输入输出样例

    输入样例#1: 
    2
    aba
    bab
    ababababac
    6
    beta
    alpha
    haha
    delta
    dede
    tata
    dedeltalphahahahototatalpha
    0
    输出样例#1: 
    4
    aba
    2
    alpha
    haha
    传送门
    AC自动机板子
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 char s[152][72],ss[1000001];
     9 int n,ch[15001][27],size,val[15001],f[15001],ans,cnt[15001],ansnum;
    10 queue<int>Q;
    11 void insert(int len,int id)
    12 {int i;
    13   int now=0;
    14   for (i=0;i<len;i++)
    15     {
    16       if (ch[now][s[id][i]-'a']==0)
    17     ch[now][s[id][i]-'a']=++size;
    18       now=ch[now][s[id][i]-'a'];
    19     }
    20   val[now]=id;
    21 }
    22 void AC_build()
    23 {int i;
    24   for (i=0;i<26;i++)
    25     if (ch[0][i])
    26       f[ch[0][i]]=0,Q.push(ch[0][i]);
    27   while (Q.empty()==0)
    28     {
    29       int u=Q.front();
    30       Q.pop();
    31       for (i=0;i<26;i++)
    32     {
    33       if (ch[u][i]) f[ch[u][i]]=ch[f[u]][i],Q.push(ch[u][i]);
    34       else ch[u][i]=ch[f[u]][i]; 
    35     }
    36     }
    37 }
    38 void query()
    39 {int i,j;
    40   int now=0;
    41   int len=strlen(ss);
    42   for (i=0;i<len;i++)
    43     {
    44       now=ch[now][ss[i]-'a'];
    45       for (j=now;j&&val[j]!=-1;j=f[j])
    46     cnt[val[j]]++;
    47     }
    48 }
    49 int main()
    50 {int i;
    51   while (cin>>n&&n)
    52     {
    53       size=0;
    54       memset(ch,0,sizeof(ch));
    55       memset(cnt,0,sizeof(cnt));
    56       memset(val,0,sizeof(val));
    57       for (i=1;i<=n;i++)
    58     {
    59       scanf("%s",s[i]);
    60       insert(strlen(s[i]),i);
    61     }
    62       AC_build();
    63       scanf("%s",ss);
    64       query();
    65       ans=0;
    66       for (i=1;i<=n;i++)
    67     if (cnt[i]>ans)
    68       {
    69         ans=cnt[i];
    70       }
    71       printf("%d
    ",ans);
    72       for (i=1;i<=n;i++)
    73     if (cnt[i]==ans)
    74       {
    75         printf("%s
    ",s[i]);
    76       }
    77     }
    78 }
  • 相关阅读:
    常用js脚本
    lotus支持的java版本
    解决传递中文参数乱码问题
    Lotus的金额大小写转换
    lotus designer 8.5中创建JAVA代理
    一步一步带你进入Java世界(一)_Java环境配置
    实例 XPages 开发一个通用的 Dojo Tree 风格定制控件
    LOTUS中B/S开发初学者问题收集
    Lotus问题收集
    R6中文参数乱码解决
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8438780.html
Copyright © 2020-2023  润新知