Ac自动机!
Ac自动机!
写这篇blog时突然回想起我普及组的时光。
我还记得备考pj时,RQY跟我们说过,他和ZJ在QBXT学ac自动机
那时候我还十分天真的问,ac自动机是什么?
现在想想,那时候的自己还真是什么也不知道。
也算了解了我pj蒟蒻时的一个梦想了吧
一定能听见青春的乐章
原谅时间太晚了
解释还是明天在发吧
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int end;
int fail;
int ch[26];
};
node tree[1000100];
int tail;
char in[1000100];
void insert(char* data)
{
int len=strlen(data);
int now=0;
for(int i=0;i<len;i++)
{
int nxt=data[i]-'a';
if(tree[now].ch[nxt]==0)
tree[now].ch[nxt]=++tail;
now=tree[now].ch[nxt];
}
tree[now].end+=1;
return ;
}
void get_fail()
{
queue<int>q;
for(int i=0;i<26;i++)
if(tree[0].ch[i])
{
tree[tree[0].ch[i]].fail=0;
q.push(tree[0].ch[i]);
}
while(!q.empty())
{
int pas=q.front();
q.pop();
for(int i=0;i<26;i++)
if(tree[pas].ch[i])
{
tree[tree[pas].ch[i]].fail=tree[tree[pas].fail].ch[i];
q.push(tree[pas].ch[i]);
}
else
tree[pas].ch[i]=tree[tree[pas].fail].ch[i];
}
}
int query(char* data)
{
int res=0;
int now=0;
int len=strlen(data);
for(int i=0;i<len;i++)
{
now=tree[now].ch[data[i]-'a'];
for(int j=now;j&&tree[j].end!=-1;j=tree[now].fail)
{
res+=tree[j].end;
tree[j].end=-1;
}
}
return res;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",in);
insert(in);
}
get_fail();
scanf("%s",in);
printf("%d",query(in));
}

浙公网安备 33010602011771号