HDU3065病毒侵袭持续中(AC自动机)

描述

传送门:我是传送门

小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?

输入

第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

输出

按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。

样例

输入

3
AA
BB
CC
ooxxCC%dAAAoen….END

输出

AA: 2
CC: 1

Note

题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。
计数策略也可一定程度上从Sample中推测。

思路

病毒侵袭实际上差不太多,也不知道我当时为什么写完病毒侵袭之后看了看这道题就放弃了。

一开始很奇怪的RE了无数次,也不知道哪里写搓了,正在要绝望的时候突然AC了···

代码

  1 /*
  2  * ==============================================
  3  *
  4  *       Filename:  C.cpp
  5  *
  6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=3065
  7  *
  8  *        Version:  1.0
  9  *        Created:  2018/09/26 23时12分29秒
 10  *       Revision:  none
 11  *       Compiler:  g++
 12  *
 13  *         Author:  杜宁元 (https://duny31030.top/), duny31030@126.com
 14  *   Organization:  QLU_浪在ACM
 15  *
 16  * ==============================================
 17  */
 18 #include <bits/stdc++.h>
 19 using namespace std;
 20 #define clr(a, x) memset(a, x, sizeof(a))
 21 #define rep(i,a,n) for(int i=a;i<=n;i++)
 22 #define pre(i,a,n) for(int i=n;i>=a;i--)
 23 #define ll long long
 24 #define max3(a,b,c) fmax(a,fmax(b,c))
 25 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 26 const double eps = 1e-6;
 27 const int INF = 0x3f3f3f3f;
 28 const int mod = 1e9 + 7;
 29 const int N = 1005;
 30 const int NN = 2001000;
 31 char m[NN];
 32 char vir[N][55];
 33 int a[N];
 34 struct node
 35 {
 36     int son[27];
 37     int fail;
 38     int count;
 39     int number;
 40 }ac[100*N];
 41 int tot = 0;
 42 void init()
 43 {
 44     clr(a,0);
 45     for(int i = 0;i < 50000;i++)
 46     {
 47         memset(ac[i].son,0,sizeof ac[i].son);
 48         ac[i].count = 0;
 49         ac[i].fail = 0;
 50         ac[i].number = 0;
 51     }
 52 }
 53 
 54 void Insert(char *s,int num)
 55 {
 56     int len = strlen(s);
 57     int now = 0;
 58     int tmp;
 59     for(int i = 0;i < len;i++)
 60     {
 61         tmp = s[i]-'A';
 62         if(ac[now].son[tmp] == 0)
 63             ac[now].son[tmp] = ++tot;
 64         now = ac[now].son[tmp];
 65     }
 66     ac[now].count++;
 67     ac[now].number = num;
 68 }
 69 
 70 void Insert1(char *s,int id)
 71 {
 72     int len = strlen(s);
 73     int now = 0;
 74     int tmp;
 75     for(int i = 0;i < len;i++)
 76     {
 77         tmp = s[i]-'A';
 78         if(ac[now].son[tmp] == 0)
 79             ac[now].son[tmp] = ++tot;
 80         now = ac[now].son[tmp];
 81     }
 82     ac[now].count++;
 83     ac[now].number = id;
 84 }
 85 
 86 void MakeFail()
 87 {
 88     queue<int> q;
 89     for(int i = 0;i < 26;i++)
 90     {
 91         if(ac[0].son[i] != 0)
 92         {
 93             ac[ac[0].son[i]].fail = 0;
 94             q.push(ac[0].son[i]);
 95         }
 96     }
 97     while(!q.empty())
 98     {
 99         int u = q.front();
100         q.pop();
101         for(int i = 0;i < 26;i++)
102         {
103             if(ac[u].son[i] != 0)
104             {
105                 ac[ac[u].son[i]].fail = ac[ac[u].fail].son[i];
106                 q.push(ac[u].son[i]);
107             }
108             else 
109                 ac[u].son[i] = ac[ac[u].fail].son[i];
110         }
111     }
112 }
113 
114 void query(char *s)
115 {
116     int len = strlen(s);
117     int now = 0,tmp;
118     for(int i = 0;i < len;i++)
119     {
120         tmp = s[i]-'A';
121         if(tmp < 0 || tmp > 25)
122             tmp = 26;
123         now = ac[now].son[tmp];
124         for(int t = now;t && ac[t].count != -1;t = ac[t].fail)
125         {
126             if(ac[t].number > 0)
127             {
128                 a[ac[t].number]++;
129             }
130             // ans += ac[t].count;
131             // ac[t].count = -1;
132         }
133     }
134     // return ans;
135 }
136 
137 int main()
138 {
139     ios
140 #ifdef ONLINE_JUDGE 
141 #else 
142         freopen("in.txt","r",stdin);
143     // freopen("out.txt","w",stdout); 
144 #endif
145     int n;
146     while(scanf("%d",&n) != EOF)
147     {
148         init();
149         rep(i,1,n)
150         {
151             scanf("%s",vir[i]);
152             Insert1(vir[i],i);
153         }
154         ac[0].fail = 0;
155         MakeFail();
156         scanf("%s",m);
157         query(m);
158         rep(i,1,n)
159         {
160             if(a[i])
161                 printf("%s: %d
",vir[i],a[i]);
162         }
163     }
164     fclose(stdin);
165     // fclose(stdout);
166     return 0;
167 }
原文地址:https://www.cnblogs.com/duny31030/p/14305082.html