题目大意:给定一个n个单词的文章,求每个单词在文章中的出现次数
题解:每加入一个串,就给这个串的路径上所有点的sum+1,表示它的前缀都又出现了一次
按照fail树中的bfs序自下而上加起来……
我的收获:AC自动机T1 get
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define idx s[i]-'a'
const int M=1000010;
int n,w[210];char s[M];
struct AC_DFA{
int tot,c[M][26],fail[M],q[M],l,r,sum[M];
void insert(int &x){
int p=0,len=strlen(s);
for(int i=0;i<len;i++){
if(!c[p][idx]) c[p][idx]=++tot;
++sum[p=c[p][idx]];
}
x=p;
}
void getfail(){
l=0,q[r=1]=0,fail[0]=-1;
while (l!=r){
int x=q[++l];
for(int i=0;i<26;i++){
if(c[x][i]) q[++r]=c[x][i],fail[c[x][i]]=!x?0:c[fail[x]][i];
else c[x][i]=!x?0:c[fail[x]][i];
}
}
}
void work(){
for(int i=r;i;i--) sum[fail[q[i]]]+=sum[q[i]];
for(int i=1;i<=n;i++) printf("%d\n",sum[w[i]]);
}
}T;
void init()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%s",s),T.insert(w[i]);
T.getfail(),T.work();
}
int main()
{
init();
return 0;
}
本文介绍了一个使用AC自动机解决字符串匹配问题的实际案例。通过构建AC自动机并利用其高效的匹配特性,实现对一篇文章中各单词出现频率的统计。文中详细展示了AC自动机的构建过程、失败指针的设置及遍历统计的方法。
652

被折叠的 条评论
为什么被折叠?



