hdu2896 病毒肆虐【AC自动机】
病毒侵袭
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 37730 Accepted Submission(s): 8348
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
aaa
bbb
ccc
2
aaabbbccc
bbaacc
total: 1
题意:
给定n个模式串,m个文本串。问每个文本串中有多少个模式串出现过,输出他们的编号。最后输出所有含有模式串的文本串个数。
思路:
暴力跑AC自动机。有一些坑点。
第一是没看到说字符是ASC码中的字符,刚开始就开了26.看题解说开256会MLE,开130左右就够了。
第二是对每个文本串进行统计时,用了一个vis数组。每一次查询一个文本串,vis应该要重新初始化。
第三是输入的字符串中会有空格,要用gets
AC自动机的题目一定要注意对每个节点进行初始化,细节方面要考虑好。
好像今天有点浮躁,写题目很草率啊。
#include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
//#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int m, n;
const int maxn = ;
const int maxlen = * + ; struct tree{
int fail;
int son[];
int ed;
bool vis;
}AC[maxlen];
int tot = ;
char s[maxlen]; void build(char s[], int id)
{
int len = strlen(s);
int now = ;
for(int i = ; i < len; i++){
if(AC[now].son[s[i]] == ){
AC[now].son[s[i]] = ++tot;
}
now = AC[now].son[s[i]];
}
AC[now].ed = id;
} void get_fail()
{
queue<int>que;
for(int i = ; i < ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i < ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
}
}
} int ans[], top = ;
int AC_query(char s[])
{
for(int i = ; i <= tot; i++){
AC[i].vis = false;
}
int len = strlen(s);
int now = , cnt = ;
for(int i = ; i < len; i++){
now = AC[now].son[s[i]];
for(int t = now; t; t = AC[t].fail){
if(!AC[t].vis && AC[t].ed != ){
ans[top] = AC[t].ed;
//cout<<ans[top]<<endl;
top++;
cnt++;
AC[t].vis = true;
if(cnt >= )return cnt;
}
}
}
return cnt;
} int main()
{
while(scanf("%d", &n) != EOF){
for(int i = ; i <= tot; i++){
AC[i].ed = ;
AC[i].fail = ;
AC[i].vis = false;
for(int j = ; j < ; j++){
AC[i].son[j] = ;
}
}
tot = ;
for(int i = ; i <= n; i++){
getchar();
gets(s);
build(s, i);
}
AC[].fail = ;
get_fail();
scanf("%d", &m);
int num = ;
for(int i = ; i <= m; i++){
getchar();
gets(s);
top = ;
if(AC_query(s)){
printf("web %d:", i);
sort(ans, ans + top);
for(int j = ; j < top; j++){
printf(" %d", ans[j]);
}
printf("\n");
num++;
}
} printf("total: %d\n", num);
} return ;
}
hdu2896 病毒肆虐【AC自动机】的更多相关文章
- hdu2896 病毒侵袭 AC自动机入门题 N(N <= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M <= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串,
/** 题目:hdu2896 病毒侵袭 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:N(N <= 500)个长度不大于200的模式串 ...
- HDU2896 病毒侵袭 —— AC自动机
题目链接:https://vjudge.net/problem/HDU-2896 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- HDu-2896 病毒侵袭,AC自动机模板题!
病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...
- hdu2896病毒侵袭(ac自动机)
链接 ac自动机的模板题 说2个注意的地方 一是题目说明包含所有ASCII字符,可以开到0-127 包含空格 题目会输入多个源串,在加完当前的val值时,不应清0,可以开个标记数组. #include ...
- hdu2896 病毒侵袭 ac自动机
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896 题目: 病毒侵袭 Time Limit: 2000/1000 MS (Java/Othe ...
- HDU2896 病毒侵袭 AC自动机模板
各种MLE,这模板感觉有问题,next数组开128也会MLE,实际上可见字符为编号32~126,只用开100就行. #include <iostream> #include <cst ...
- hdu 2896 病毒侵袭 ac自动机
/* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...
- 【Luogu2444】病毒(AC自动机)
[Luogu2444]病毒(AC自动机) 题面 洛谷 题解 如果存在一个无限长的串 证明可以在\(AC\)自动机上找到一个环 然后在上面可以无限跳 所以构建\(AC\)自动机 在上面跑\(dfs\)就 ...
- hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 2021.11.10 [POI2000]病毒(AC自动机)
2021.11.10 [POI2000]病毒(AC自动机) https://www.luogu.com.cn/problem/P2444 题意: 二进制病毒审查委员会最近发现了如下的规律:某些确定的二 ...
随机推荐
- python 上下文处理错误,记录日志
之前发过了装饰器版本的异常记录日志,但是需要装饰在函数或方法上.此篇用上下文管理,用一个with就能记录错误了,不需要写成函数. import traceback # pip install mult ...
- iOS6 中 Smart App Banners介绍和使用(转自COCOACHINA.COM)
转自:http://www.cocoachina.com/applenews/devnews/2012/0924/4842.html iOS 6新增Smart App Banners,也就是“智能Ap ...
- Java并发编程、内存模型与Volatile
http://www.importnew.com/24082.html volatile关键字 http://www.importnew.com/16142.html ConcurrentHash ...
- struts开发<struts中的參数传递.三>
不说废话,直接上干货 1.通过set和get传递參数 添加username 和password两个属性并添加set和get方法 package fzl.user.struts.demo; import ...
- java痛苦学习之路[十]--日常问题汇总
FIddler2 1.FIddler2 request请求的參数出现中文乱码问题时,须要进行一下设置: 打开注冊表编辑器,找到HKCU\Software\Microsoft\Fiddler 2\,在 ...
- 升级MAC OX上的Python到3.4
第1步:下载Python3.4 下载地址如下: 下载Mac OS X 64-bit/32-bit installerhttps://www.python.org/downloads/release/p ...
- Linux用户态程序计时方式详解
前言 良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序 ...
- WP8.1学习系列(第一章)——添加应用栏
做过android开发的同学们应该都知道有个ActionBar的头部操作栏,而wp也有类似的一个固定在app页面里通常拥有的内部属性,就是应用栏.以前叫做ApplicationBar,现在wp和win ...
- 【Linux】python 2.x 升级 python3.x 之后 yum命令出现except OSError, e: ^ SyntaxError: invalid syntax
python2.7升级到python3.6.4 文章链接 : https://zhuanlan.zhihu.com/p/33660059 我在服务器上.把linux默认安装的python2.7 升级 ...
- Esper学习之七:EPL语法(三)
1.Aggregation 和SQL一样,EPL也有Aggregation,即聚合函数.语法如下: aggregate_function([all|distinct] expression) aggr ...