HDU 3065 病毒侵袭持续中 AC自动机

HDU 3065

AC自动机 这个也可以拿来做模板了,使用静态数组模拟建树

  1 //#pragma comment(linker, "/STACK:1677721600")
  2 #include <map>
  3 #include <set>
  4 #include <stack>
  5 #include <queue>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cctype>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 #define INF 0x3f3f3f3f
 17 #define inf (-((LL)1<<40))
 18 #define lson k<<1, L, (L + R)>>1
 19 #define rson k<<1|1,  ((L + R)>>1) + 1, R
 20 #define mem0(a) memset(a,0,sizeof(a))
 21 #define mem1(a) memset(a,-1,sizeof(a))
 22 #define mem(a, b) memset(a, b, sizeof(a))
 23 #define FIN freopen("in.txt", "r", stdin)
 24 #define FOUT freopen("out.txt", "w", stdout)
 25 #define rep(i, a, b) for(int i = a; i <= b; i ++)
 26 #define dec(i, a, b) for(int i = a; i >= b; i --)
 27
 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 32
 33 //typedef __int64 LL;
 34 typedef long long LL;
 35 const int MAXN = 1000 + 100;
 36 const int MAXM = 2000000 + 100;
 37 const double eps = 1e-8;
 38 LL MOD = 1000000007;
 39
 40
 41 const int SIGMA_SIZE = 27;
 42 const int MAX_LEN = 52;
 43
 44 struct ACMachine {
 45     int ch[MAXN * MAX_LEN][SIGMA_SIZE];
 46     int val[MAXN * MAX_LEN];
 47     int fail[MAXN * MAX_LEN];
 48     int last[MAXN * MAX_LEN];
 49
 50     int id[MAXN * MAX_LEN], ans[MAXN];
 51
 52     int node_cnt;
 53     queue<int>q;
 54
 55     void init() {
 56         node_cnt = 0;
 57         mem0(ch); mem0(val);
 58         mem0(fail); mem0(last);
 59         while(!q.empty()) q.pop();
 60     }
 61     int get_idx(char ch) {
 62         if(ch >= ‘A‘ && ch <= ‘Z‘)
 63             return ch - ‘A‘;
 64         return 26;
 65     }
 66     void insert_to_tree(char *str, int p) {
 67         int u = 0, len = strlen(str);
 68         rep (i, 0, len - 1) {
 69             int c = get_idx(str[i]);
 70             if(!ch[u][c]) {
 71                 ch[u][c] = ++node_cnt;
 72             }
 73             u = ch[u][c];
 74         }
 75         val[u] ++;
 76
 77         id[u] = p;
 78     }
 79     void get_fail() {
 80         rep (c, 0, SIGMA_SIZE - 1) {
 81             int u = ch[0][c];
 82             if(u) q.push(u);
 83         }
 84         while(!q.empty()) {
 85             int r = q.front(); q.pop();
 86             rep (c, 0, SIGMA_SIZE - 1) {
 87                 int u = ch[r][c];
 88                 if(!u) {
 89                     ch[r][c] = ch[fail[r]][c];
 90                     continue;
 91                 }
 92                 q.push(u);
 93                 int v = fail[r];
 94                 while(v && !ch[v][c]) v = fail[v];
 95                 fail[u] = ch[v][c];
 96                 last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
 97             }
 98         }
 99     }
100     void find_ans(char *str) {
101
102         mem0(ans);
103
104         int len = strlen(str), u = 0;
105         rep(i, 0, len - 1) {
106             int c = get_idx(str[i]);
107             u = ch[u][c];
108             int v = u;
109             while(v) {
110                 if(val[v]) {
111                     ans[id[u]] ++;
112                 }
113                 v = last[v];
114             }
115         }
116
117     }
118 }acm;
119
120 int n;
121 char str[MAXM], s[MAXN][MAX_LEN];
122
123 int main()
124 {
125 //    FIN;
126     while(~scanf("%d%*c", &n)) {
127         acm.init();
128         rep (i, 1, n) {
129             scanf("%s", s[i]);
130             acm.insert_to_tree(s[i], i);
131         }
132         acm.get_fail();
133         scanf("%s", str);
134         acm.find_ans(str);
135         rep (i, 1, n) if(acm.ans[i]){
136             printf("%s: %d\n", s[i], acm.ans[i]);
137         }
138     }
139     return 0;
140 }
时间: 2024-10-18 08:36:56

HDU 3065 病毒侵袭持续中 AC自动机的相关文章

HDU 3065 病毒侵袭持续中 AC自动机题解

其实本题比HDU的病毒侵袭1还简单,不过有一个陷阱卡到我了:就是搜索text的时候,当遇到的字母不是大写字母的时候,那么就要重新从根节点开始搜索,否则就会答案错误. 那么一点陷阱,居然没想到啊. 教训啊:看来对不太平常的地方,需要更加深入的思考,才能发现其中的陷阱,否则就WA了. #include <stdio.h> #include <string.h> #include <queue> using std::queue; const int MAX_N = 1001

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

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15137    Accepted Submission(s): 5161 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

hdu 3065 病毒侵袭持续中 AC自动机模板题 ,,一A。

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7685    Accepted Submission(s): 2687 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

hdu 3056 病毒侵袭持续中 AC自动机

http://acm.hdu.edu.cn/showproblem.php?pid=3065 刘汝佳的模板真的很好用,这道题直接过 学到: cnt数组记录单词出现次数 以及map存储单词编号与字符串,便于处理相关信息 上代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> #include <str

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

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过程进行修改,对于每个节点,需要从该节点的失败指针回溯, 如果失败指针回溯后的节点为某个模式串的最后一个节点,则匹配了另一个模式串: 代码如下: #include <queue> #include <cstdio> #include <cstring> #include &l

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含"英文大写字符".当然小t好想好想为民除害,但是小t从来不打没有准备的战争.知己知彼,百战不殆,小t首先要

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

题目链接:病毒侵袭持续中 解析:用end数组标记病毒编号,用used数组记录各个病毒出现的次数,最后对应输出即可. AC代码: #include <bits/stdc++.h> using namespace std; const int maxn = 1002; const int max_word = 52; const int max_text = 2000002; const int sigma_size = 128; char buf[max_text], vir[maxn][max

HDU 3065 病毒侵袭持续中(AC自己主动机)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒站点,他有着好多好多的病毒.可是这个站点包括的病毒非常奇怪,这些病毒的特征码非常短,并且仅仅包括"英文大写字符".当然小t好想好想为民除害,可是小t从来不打没有准备的战争.知己知彼,百战不殆.小

hdu3065 病毒侵袭持续中 AC自动机入门题 N(N &lt;= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数. 思路:ac自动机做发,val标记每一个病毒串编号,通过print函数统计每一个病毒出现的次数. AC自动机好文章:http://www.cppblog.com/menjitianya/archi