HDU 3065 病毒侵袭持续中(AC自动机)
2016-04-26 09:21
387 查看
病毒侵袭持续中
Problem Description小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
Input
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
Output
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
Sample Input
3 AA BB CC ooxxCC%dAAAoen....END
Sample Output
AA: 2 CC: 1 Hint Hit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。
PS:题目的数据好像比之前的数据水了一些,竟然让我1A了。【有关于AC自动机的讲解AC自动机】
不多说,还是AC自动机,本题需要注意的地方是可重叠匹配,直接上模板就好,在字典树id上做点小手脚换为字串的ID,在最后匹配的时候非大写英文字母我们直接让返回到root就可以,其他的就没什么了。
#include <algorithm> #include <iostream> #include <numeric> #include <cstring> #include <iomanip> #include <string> #include <vector> #include <cstdio> #include <queue> #include <stack> #include <cmath> #include <map> #include <set> #define LL long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const LL M = 100099; const double esp = 1e-6; const double PI = 3.14159265359; const LL INF = 0x3f3f3f3f; using namespace std; char arr[2000100]; char str[1010][60]; int vis[1010]; struct node{ node *next[26]; node *fail; int count; void init(){ for(int i=0;i<26;i++) next[i] = NULL; fail = NULL; count = 0; } }*root; void insert(int Pos){ node *cp = root; int len = strlen(str[Pos]); for(int i=0;i<len;i++){ int t = str[Pos][i] - 'A'; if(cp->next[t] == NULL){ cp->next[t] = new node; cp->next[t]->init(); cp = cp->next[t]; } else cp = cp->next[t]; } cp->count = Pos; } void Get_fail(){ queue<node*>Q; node *p = root,*son,*temp; Q.push(p); while(!Q.empty()){ temp = Q.front();Q.pop(); for(int i=0;i<26;i++){ son = temp->next[i]; if(son != NULL){ if(temp == root){ son->fail = root; } else{ p = temp->fail; while(p){ if(p->next[i]){ son->fail = p->next[i]; break; } p = p->fail; } if(!p) son->fail = root; } Q.push(son); } } } } void cal_ans(){ Get_fail(); int len = strlen(arr); node *p,*temp; p = root; for(int i=0;i<len;i++){ if(arr[i] >= 'A' && arr[i] <= 'Z'){ int t = arr[i] - 'A'; while(!p->next[t] && p!=root) p = p->fail; p = p->next[t]; if(p == NULL) p = root; temp = p; while(temp!=root){ if(temp->count > 0){ vis[temp->count]++; } else break; temp = temp->fail; } } else p = root; } } int main(){ int n; while(~scanf("%d",&n)){ root = new node; root->init(); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++){ scanf("%s",str[i]); insert(i); } scanf("%s",arr); cal_ans(); for(int i=1;i<=n;i++){ if(vis[i] > 0){ printf("%s: %d\n",str[i],vis[i]); } } } return 0; }
相关文章推荐
- starUML使用教程
- 他只卖雨伞却做到了日入千元——上
- win7开机后svchost..exe占用CPU和内存很高的解决方法
- Java的各种工具类
- IOS延时执行函数详解
- [CareerCup] 17.8 Contiguous Sequence with Largest Sum 连续子序列之和最大
- sql语句为某一列添加或者删除某些字段
- 史上最全的maven pom.xml文件教程详解
- docker 中配置mongodb并对外暴露链接端口设置账户认证,防止脱裤
- Jquery - Javascript 基本问题汇总
- CSS伪元素和伪类
- 什么是服务器证书?哪些网站需要HTTPS(SSL证书)
- Equals和词典
- (GeoTrust 企业(OV)型 增强版(EV) SSL证书
- Delphi 编写COM+组件的知识和样例
- 关于DatagridView里面选择框选择改变处理
- 监听器-java同步的基本思想
- 又学一招——EF程序集未引用报错
- 线上bug重现方法之一(捌点钟学院)
- 数据库存储过程