【USACO】AC自动机

Description

对,这就是裸的AC自动机。 
要求:在规定时间内统计出模版字符串在文本中出现的次数。

Input

第一行:模版字符串的个数N。 
第2->N+1行:N个字符串。(每个模版字符串的长度<=50) 
第N+2行:一行很长的字符串。长的很。(使用AC自动机能在1s内计算出)

Output

共N行,每行输出一个模版及出现的次数。(之间有一个空格,按照输入顺序输出)

Sample Input


hers 
her 
his 
she 
shershisher

Sample Output

hers 1 
her 2 
his 1 
she 2

Hint

所有字母均为小写 
所给模版不会重复

模版题 贴代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6  
 7 struct Lin
 8 {
 9     int next[27];
10     int cnt,id;
11 }a[10001];
12 char s[10000001];
13 int fail[10001];
14 int ans[10001];
15 char o[10001][51];
16 int num=0;
17  
18 void work(int x)
19 {
20     scanf("%s",o[x]);
21     int ls=strlen(o[x]);int u;
22     int p=0;
23     for(int i=0;i<ls;i++)
24     {
25         u=o[x][i]-'a';
26         if(a[p].next[u])p=a[p].next[u];
27         else
28         {
29             a[p].next[u]=++num;
30             p=num;
31         }
32     }
33     a[p].cnt++;
34     a[p].id=x;
35 }
36  
37 void getfail()
38 {
39     queue<int>q;
40     q.push(0);
41     int u,v,p;
42     while(!q.empty())
43     {
44         u=q.front();
45         q.pop();
46         for(int i=0;i<26;i++)
47         {
48             v=a[u].next[i];
49             if(!v)continue;
50             p=fail[u];
51             while(p)
52             {
53                 if(a[p].next[i])
54                 {
55                     break;
56                 }
57                 p=fail[p];
58             }
59             if(a[p].next[i] && a[p].next[i]!=v)fail[v]=a[p].next[i];
60             q.push(v);
61         }
62     }
63 }
64 void getanswer()
65 {
66     scanf("%s",s);
67     int p=0;int ls=strlen(s);int u;int go;
68     for(int i=0;i<ls;i++)
69     {
70         u=s[i]-'a';
71         while(!a[p].next[u] && p)p=fail[p];
72         p=a[p].next[u];
73         go=p;
74         while(go)
75         {
76             ans[a[go].id]+=a[go].cnt;
77             go=fail[go];
78         }
79     }
80     return ;
81 }
82  
83 int main()
84 {
85     int n;
86     scanf("%d",&n);
87     for(int i=1;i<=n;i++)
88     work(i);
89     getfail();
90     getanswer();
91     for(int i=1;i<=n;i++)
92     printf("%s %d\n",o[i],ans[i]);
93     return 0;
94 }

 

 
posted @ 2017-05-16 16:21  PIPIBoss  阅读(312)  评论(0编辑  收藏  举报