这题数据太水,一开始没有加上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. LintCode Validate Binary Search Tree

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

  2. RestTemplate 请求url

    1.get 请求 RestTemplate restTemplate = new RestTemplate(); String url = ""; JSONObject resul ...

  3. iOSapp的json告示

    看到这篇文章,要知道这篇文章告诉你什么,就是对json的解析的一个解释,解析的代码去百度就可以了,OC的.安卓的.JS的等等都很多,但是对于swift语言的小白来说,资料就少之又少,包括一些看不懂的, ...

  4. UVa 679 小球下落

    题意:这道题规律性极强,虽然是二叉树,但是可以用模拟来写. 1<<20 意思是1的二进制左移20位,即2的20次方. 对于二叉树中一个节点 k ,其左节点,右节点的编号分别是2k 和 2k ...

  5. Codeforces Round #341 Div.2 A. Wet Shark and Odd and Even

    题意是得到最大的偶数和 解决办法很简单 排个序 取和 如果是奇数就减去最小的奇数 #include <cstdio> #include <cmath> #include < ...

  6. java json-lib.jar

    import java.util.ArrayList; import java.util.Date; import java.util.List; import net.sf.json.JSONObj ...

  7. Python的regex模块——更强大的正则表达式引擎

    Python自带了正则表达式引擎(内置的re模块),但是不支持一些高级特性,比如下面这几个: 固化分组    Atomic grouping 占有优先量词    Possessive quantifi ...

  8. WeX5之xid相关API

    WeX5针对xid提供了以下js api: 1.根据xid获取id:this.getIDByXID(xid): 2.根据xid获取HTML节点:this.getElementByXid(xid),此a ...

  9. mfc_随机数生成器

    vc++6.0 内涵图

  10. python分布式任务调度Celery

    Celery是Python开发的分布式任务调度模块,今天抽空看了一下,果然接口简单,开发容易,5分钟就写出了一个异步发送邮件的服务. Celery本身不含消息服务,它使用第三方消息服务来传递任务,目前 ...