您的位置:首页 > 其它

hdu 3065 病毒侵袭持续中 ac自动机模板题

2015-09-03 13:11 393 查看
窝今天果断翻了SB,main函数中忘记写ac.bfs()这句话了,然后各种单步调试感觉怎么这个fail数组那么奇怪呢...很无语...后来不小心发现了果断AC,基本和上一道题类似,不过就是第几个字符串出现几次就对应的下标++,最后输出就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define N 2000000
int ans[1234];
char s[1234][52];
char v[3000000];
struct Trie
{
int next
[27],fail
,mark
;
int root,L;
int newnode()
{
memset(next[L],-1,sizeof(next[L]));
mark[L]=0;
fail[L++]=-1;
return L-1;
}
void go()
{
L=0;
root=newnode();
}
void init(char *v,int id)
{
int p=root;
for(int i=0;v[i];i++)
{
int tep=v[i]-'A';
if(next[p][tep]==-1) next[p][tep]=newnode();
p=next[p][tep];
}
mark[p]=id;
}
void bfs()
{
queue<int>q;
q.push(root);
while(!q.empty())
{
int p=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(next[p][i]==-1)
{
if(p==root) next[p][i]=root;
else next[p][i]=next[fail[p]][i];
}
else
{
if(p==root) fail[next[p][i]]=root;
else fail[next[p][i]]=next[fail[p]][i];
q.push(next[p][i]);
}
}
}
}
void finde(char *v)
{
int p=root,q;
for(int i=0;v[i];i++)
{
if(v[i]<'A'||v[i]>'Z')
{
p=root;
continue;
}
int tep=v[i]-'A';
while(next[p][tep]==-1&&p!=root)
p=fail[p];
p=next[p][tep];
if(p==-1) p=root;
q=p;
while(q!=root)
{
if(mark[q]!=0)
ans[mark[q]]++;
q=fail[q];
}
}
}
} ac;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(ans,0,sizeof(ans));
ac.go();
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
ac.init(s[i],i);
}
ac.bfs();
scanf("%s",v);
ac.finde(v);
for(int i=1;i<=n;i++)
{
if(ans[i]==0)
continue;
printf("%s: %d\n",s[i],ans[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: