HDU 3065 病毒侵袭持续中

来源:互联网 发布:义乌淘宝装修 编辑:程序博客网 时间:2024/05/01 23:11

目标串中各个模式串出现了几次

这就更简单了,都不用把out标记成false了

题目中的病毒都是大写字母这个条件应该怎么用?

#include <cstdio>#include <cstdlib>#include <string>#include <climits>#include <iostream>#include <vector>#include <set>#include <cmath>#include <cctype>#include <algorithm>#include <sstream>#include <map>#include <cstring>#include <queue>using namespace std;//MAX_NODE = StringNumber * StringLengthconst int MAX_NODE = 50010;//节点个数,一般字符形式的题26个const int CHILD_NUM = 128;//特定题目需要char test[2000010];int cnt[1010];char vernus[1010][50];class ACAutomaton {private://每个节点的儿子,即当前节点的状态转移int chd[MAX_NODE][CHILD_NUM];//记录题目给的关键数据int val[MAX_NODE];//传说中的fail指针int fail[MAX_NODE];//队列,用于广度优先计算fail指针int Q[MAX_NODE];//字母对应的ID//int ID[128];//已使用节点个数int sz;public://初始化,计算字母对应的儿子ID,如:'a'->0 ... 'z'->25void Initialize() {fail[0] = 0;//for (int i = 0 ; i < CHILD_NUM ; i ++) {//ID[i+base] = i;//}}//重新建树需先Resetvoid Reset() {memset(chd[0] , 0 , sizeof(chd[0]));sz = 1;}//将权值为key的字符串a插入到trie中void Insert(char *a,int key) {int p = 0;for ( ; *a ; a ++) {//int c = ID[*a];int c = *a;if (!chd[p][c]) {memset(chd[sz] , 0 , sizeof(chd[sz]));val[sz] = 0;chd[p][c] = sz ++;}p = chd[p][c];}val[p] = key;}//建立AC自动机,确定每个节点的权值以及状态转移void Construct() {int *s = Q , *e = Q;for (int i = 0 ; i < CHILD_NUM ; i ++) {if (chd[0][i]) {fail[ chd[0][i] ] = 0;*e ++ = chd[0][i];}}while (s != e) { /*广度优先。 关键*/int u = *s++;for (int i = 0 ; i < CHILD_NUM ; i ++) {int &v = chd[u][i];if (v) {*e ++ = v; /*当前结点的失败指针 等于  父节点的失败指针指向的结点的的同个字母儿子结点的指针*/fail[v] = chd[ fail[u] ][i]; //以下一行代码要根据题目所给val的含义来写//val[v] |= val[ fail[v] ];} else {v = chd[ fail[u] ][i];}}}}//解题,特定题目需要void Work(){memset(cnt, 0, sizeof(cnt));int n = strlen(test);int p = 0;for(int i = 0; i < n; i++){//int next = ID[test[i]];//if(!isupper(test[i]))//continue;int next = test[i];int tmp = p = chd[p][next];while(val[tmp] != 0){cnt[val[tmp]]++;//val[tmp] = 0; tmp = fail[tmp];}}}}AC;int main() {AC.Initialize();int n;while(scanf("%d", &n) != EOF){AC.Reset();for(int i = 1; i <= n; i++){scanf("%s", &vernus[i]);AC.Insert(vernus[i], i);}scanf("%s", test);AC.Construct();AC.Work();for(int i = 1; i <= n; i++){if(cnt[i] > 0)printf("%s: %d\n", vernus[i], cnt[i]);}}return 0;}