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

时间:2021-10-07 00:18:04

题目:戳这里

题意:输出主串中出现的模式串以及该模式串出现的次数。

思路:ac自动机,匹配的时候对应的vis[]+1即可

代码:

HDU 3065 病毒侵袭持续中(AC自动机)HDU 3065 病毒侵袭持续中(AC自动机)
#include<stdio.h>
#include
<string.h>
#include
<algorithm>
#include
<queue>
using namespace std;
const int maxw = 26;
const int maxn = 55;
const int time = 1010;
const int maxs = 2000005;
struct Tire
{
int tire[maxn*time][maxw];
int fail[maxn*time];
int tag[maxn*time];
int vis[time];
int P, root;
int New()
{
for(int i=0; i<maxw; i++) tire[P][i]=-1;
tag[P]
=0;
return P++;
}
void init()
{
P
=0;
root
=New();
}
void Insert(char ch[], int id)
{
int now = root;
for(int i=0; ch[i]; i++)
{
if(tire[now][ch[i]-'A']==-1) tire[now][ch[i]-'A'] = New();
now
= tire[now][ch[i]-'A'];
}
tag[now]
= id;
}
void build()
{
queue
<int>Q;
for(int i=0; i<maxw; i++)
{
if(tire[root][i]!=-1)
{
fail[tire[root][i]]
= root;
Q.push(tire[root][i]);
}
else tire[root][i] = root;
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
for(int i=0; i<maxw; i++)
{
if(tire[now][i]!=-1)
{
fail[tire[now][i]]
= tire[fail[now]][i];
Q.push(tire[now][i]);
}
else tire[now][i] = tire[fail[now]][i];
}
}
}
void match(char ch[])
{
int now = root;
memset(vis,
0,sizeof(vis));
for(int i=0; ch[i]; i++)
{
if(ch[i]<'A'||ch[i]>'Z') now = root;
else
{
now
= tire[now][ch[i]-'A'];
int tmp = now;
while(tmp!=0)
{
if(tag[tmp]) vis[tag[tmp]]++;
tmp
= fail[tmp];
}
}
}
}
};
char ch[time][maxn], def[maxs];
int n;
Tire ac;
int main()
{
while(~scanf("%d",&n))
{
ac.init();
for(int i=1; i<=n; i++)
{
scanf(
"%s",ch[i]);
ac.Insert(ch[i],i);
}
ac.build();
scanf(
"%s",def);
ac.match(def);
for(int i=1; i<=n; i++)
{
if(ac.vis[i]!=0)
printf(
"%s: %d\n",ch[i],ac.vis[i]);
}
}
}
View Code