这题数据太水,一开始没有加上Get的方法也能AC。。话说AC自动机中一定要注意加上Get的方法!(不然,同一个后缀的其他单词就没被算上了。)

  代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = * + ; int ans[+];
map<int,string> M; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s,int which)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'A'])
stateTable[now].nxt[c-'A'] = size++;
now = stateTable[now].nxt[c-'A'];
}
stateTable[now].cnt = which;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} void Get(int u)
{
while(u)
{
ans[stateTable[u].cnt] ++;
u = stateTable[u].fail;
}
} void match(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(c<'A' || c>'Z') {now = ;continue;}
if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'A'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'A'];
}
if(stateTable[now].cnt)
{
Get(now);
//ans[stateTable[now].cnt] ++;
/*
一定要用Get这样的方法,
不然,同一个后缀的无法被算上了
*/
}
}
}
}aho; int n;
char s[MAX_N]; int main()
{
while(scanf("%d",&n)==)
{
memset(ans,,sizeof(ans));
M.clear();
aho.init();
for(int i=;i<=n;i++)
{
scanf("%s",s);
M[i] = s;
aho.insert(s,i);
}
aho.build();
scanf("%s",s);
aho.match(s);
for(int i=;i<=n;i++)
{
if(ans[i])
{
cout << M[i] << ": " << ans[i] << endl;
}
}
}
}

————————————————————————————————————————————

  发现上面的代码有问题(虽然能AC),正确代码如下:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int MAX_N = + ;
const int MAX_Tot = * + ; int ans[+];
map<int,string> M; struct Aho
{
struct state
{
int nxt[];
int fail,cnt;
}stateTable[MAX_Tot]; int size; queue<int> que; void init()
{
while(que.size()) que.pop();
for(int i=;i<MAX_Tot;i++)
{
memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
stateTable[i].fail = stateTable[i].cnt = ;
}
size = ;
} void insert(char *s,int which)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(!stateTable[now].nxt[c-'A'])
stateTable[now].nxt[c-'A'] = size++;
now = stateTable[now].nxt[c-'A'];
}
stateTable[now].cnt = which;
} void build()
{
stateTable[].fail = -;
que.push(); while(que.size())
{
int u = que.front();que.pop();
for(int i=;i<;i++)
{
if(stateTable[u].nxt[i])
{
if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
else
{
int v = stateTable[u].fail;
while(v != -)
{
if(stateTable[v].nxt[i])
{
stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
break;
}
v = stateTable[v].fail;
}
if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
}
que.push(stateTable[u].nxt[i]);
}
}
}
} void Get(int u)
{
while(u)
{
ans[stateTable[u].cnt] ++;
u = stateTable[u].fail;
}
} void match(char *s)
{
int n = strlen(s);
int now = ;
for(int i=;i<n;i++)
{
char c = s[i];
if(c<'A' || c>'Z') {now = ;continue;}
if(stateTable[now].nxt[c-'A']) now = stateTable[now].nxt[c-'A'];
else
{
int p = stateTable[now].fail;
while(p != - && stateTable[p].nxt[c-'A'] == ) p = stateTable[p].fail;
if(p == -) now = ;
else now = stateTable[p].nxt[c-'A'];
}
//if(stateTable[now].cnt)
{
Get(now);
}
}
}
}aho; int n;
char s[MAX_N]; int main()
{
while(scanf("%d",&n)==)
{
memset(ans,,sizeof(ans));
M.clear();
aho.init();
for(int i=;i<=n;i++)
{
scanf("%s",s);
M[i] = s;
aho.insert(s,i);
}
aho.build();
scanf("%s",s);
aho.match(s);
for(int i=;i<=n;i++)
{
if(ans[i])
{
cout << M[i] << ": " << ans[i] << endl;
}
}
}
}
/*
3
ABCDEFG
ABCDE
DEF
ABCDEFG
*/

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

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

    题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...

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

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过 ...

  3. HDU 3065 病毒侵袭持续中

    HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. hdu 3065 病毒侵袭持续中【AC自动机】

    <题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...

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

    /** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...

  7. hdu----(3065)病毒侵袭持续中(AC自动机)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. hdu 3065病毒侵袭持续中

    病毒侵袭持续中 http://acm.hdu.edu.cn/showproblem.php?pid=3065 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  9. HDU 3065 病毒侵袭持续中 (模板题)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  10. HDU3065 病毒侵袭持续中 —— AC自动机

    题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

随机推荐

  1. 使用JavaScript设置、获取父子页面中的值

    一:获取父页面中的值 有二种方法windows.open()和windows.showModalDialog() 1.windos.open(URL,name,reatures,replace) 再父 ...

  2. UVa 四叉树

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. linux之各个文件夹作用

    /bin 二进制可执行命令  /dev 设备特殊文件  /etc 系统管理和配置文件  /etc/rc.d 启动的配置文件和脚本  /home 用户主目录的基点,比如用户user的主目录就是/home ...

  4. JAVA 对象引用,以及对象赋值

    注:引自http://zwmf.iteye.com/blog/1738574 关键字: java对象 引用 Java对象及其引用 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里, ...

  5. webpack-dev-server、webpack-dev-middleware、webpack-hot-middleware区别

    webpack-dev-server: 它是一个静态资源服务器,只用于开发环境: webpack-dev-server会把编译后的静态文件全部保存在内存里: webpack-dev-middlewar ...

  6. java 里面的string 和byte[] 怎么互转

    public class TestBytes { private static String FORMAT = "UTF-8"; public static void main(S ...

  7. SQL级联删除——删除主表同时删除从表——同时删除具有主外键关系的表

    create table a(id  varchar(20) primary key,password varchar(20) not null) create table b(id int iden ...

  8. python学习-day12:列表、元祖、字典介绍和内置

    list:列表 >>>----可以被修改.修改成元素,元素可以使单独的数字,也可以是:新的list. 通过:链表..每个元素存储的时候,同时会指向下一个元素. 二.list编辑修改方 ...

  9. int和NSInteger区别

    NSInteger会自动根据操作系统的位数(32或者64位)返回最大的类型 查到c语言中,int和long的字节数是和操作系统指针所占位数相等. 但c语言中说,long的长度永远大于或等于int ob ...

  10. JavaScript 数据验证类

    JavaScript 数据验证类 /* JavaScript:验证类 author:杨波 date:20160323 1.用户名验证 2.密码验证 3.重复密码验证 4.邮箱验证 5.手机号验证 6. ...