HDU 3065 - 病毒侵袭持续中 (AC自动机)
2014-08-03 15:01
393 查看
病毒侵袭持续中
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6017 Accepted Submission(s): 2154
[align=left]Problem Description[/align]
小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
[align=left]Input[/align]
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
[align=left]Output[/align]
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
[align=left]Sample Input[/align]
3 AA BB CC ooxxCC%dAAAoen....END
[align=left]Sample Output[/align]
AA: 2 CC: 1 Hint Hit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。
[align=left]Source[/align]
2009 Multi-University Training Contest 16 - Host by NIT
[align=left]Recommend[/align]
lcy | We have carefully selected several similar problems for you: 2243 2825 3247 3341 2296
AC自动机模板题
#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <string> #include <map> #include <cmath> #include <queue> #include <set> using namespace std; //#define WIN #ifdef WIN typedef __int64 LL; #define iform "%I64d" #define oform "%I64d\n" #define oform1 "%I64d" #else typedef long long LL; #define iform "%lld" #define oform "%lld\n" #define oform1 "%lld" #endif #define S64I(a) scanf(iform, &(a)) #define P64I(a) printf(oform, (a)) #define P64I1(a) printf(oform1, (a)) #define REP(i, n) for(int (i)=0; (i)<n; (i)++) #define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++) #define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++) const int INF = 0x3f3f3f3f; const double eps = 10e-9; const double PI = (4.0*atan(1.0)); const int MAX_NODE = 500000 + 20; const int SIGMA_SIZE = 108; struct ACAutomata { int ch[MAX_NODE][SIGMA_SIZE]; int val[MAX_NODE]; int f[MAX_NODE]; int last[MAX_NODE]; int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } int idx(char c) { return c - 20; } void insert(char * s, int v) { int n = strlen(s); int u = 0; for (int i=0; i<n; i++) { int c = idx(s[i]); if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } void build() { queue<int> Q; f[0] = 0; for (int i=0; i<SIGMA_SIZE; i++) { int u = ch[0][i]; if(u) { Q.push(u); f[u] = last[u] = 0; } } while (!Q.empty()) { int r = Q.front(); Q.pop(); for (int c=0; c<SIGMA_SIZE; c++) { int u = ch[r][c]; if(!u) continue; Q.push(u); int v = f[r]; while (v && !ch[v][c]) v = f[v]; f[u] = ch[v][c]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } void add(int j) { if(j) { val[j]++; add(last[j]); } } void query(char * T) { int n = strlen(T); int j = 0; for (int i=0; i<n; i++) { int c = idx(T[i]); while(j && !ch[j][c]) j = f[j]; j = ch[j][c]; if(val[j]) add(j); else if(last[j]) add(last[j]); } } int cnt(char * s) { int u = 0; int n = strlen(s); for(int i=0; i<n; i++) { int c = idx(s[i]); u = ch[u][c]; } return val[u] - 1; } }; ACAutomata ac; char dic[1020][60]; char s[2000000 + 20]; int main() { int n; while(scanf("%d", &n) != EOF) { ac.init(); for(int i=0; i<n; i++) { scanf("%s", dic[i]); ac.insert(dic[i], 1); } ac.build(); scanf("%s", s); ac.query(s); for(int i=0; i<n; i++) { int cnt = ac.cnt(dic[i]); if(cnt > 0) printf("%s: %d\n", dic[i], cnt); } } return 0; }
相关文章推荐
- HDU 3065 病毒侵袭持续中 (AC自动机)
- hdu 3065 病毒侵袭持续中 (ac自动机)
- HDU-3065-病毒侵袭持续中-AC自动机
- hdu 3065 病毒侵袭持续中 - AC自动机
- HDU 3065 病毒侵袭持续中 (AC自动机)
- hdu 3065 病毒侵袭持续中 (AC自动机)
- HDU 3065 病毒侵袭持续中 (AC自动机)
- HDU 3065 病毒侵袭持续中 AC自动机
- HDU 3065 病毒侵袭持续中 (AC自动机)
- AC自动机专题——C - 病毒侵袭持续中 HDU - 3065
- HDU 3065 病毒侵袭持续中 | AC自动机
- hdu 3065 病毒侵袭持续中 (ac 自动机)
- hdu 3065 病毒侵袭持续中 AC自动机
- HDU 3065 病毒侵袭持续中 (AC自动机)
- HDU 3065 病毒侵袭持续中 (AC自动机)
- HDU 3065 病毒侵袭持续中 (AC自动机)
- HDU 3065 病毒侵袭持续中 (AC自动机)
- 病毒侵袭持续中 (HDU_3065) AC自动机
- HDU-2896 病毒侵袭 && HDU-3065 病毒侵袭持续中(AC自动机)
- hdu 3065 病毒侵袭持续中 ac_automaton