AC自动机模板1
AC自动机模板1
学习AC自动机
我是看的学的yyb的博客
然后我自己写的Junlier的AC自动机
code
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#include<vector>
#define rg register
#define il inline
#define lst long long
#define ldb long double
#define N 1000050
using namespace std;
const int Inf=1e9;
int n,cnt;
string s;
struct TRIE{
int fail,end;
int son[27];
}ljl[N];
il int read()
{
rg int s=0,m=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
il void Insert()
{
rg int len=s.length();
rg int now=0;
for(rg int i=0;i<len;++i)
{
rg int kk=s[i]-'a';
if(!ljl[now].son[kk])
ljl[now].son[kk]=++cnt;
now=ljl[now].son[kk];
}
ljl[now].end++;
}
il void get_fail()
{
queue<int> Q;
while(!Q.empty())Q.pop();
for(rg int i=0;i<26;++i)
{
if(ljl[0].son[i])
{
ljl[ljl[0].son[i]].fail=0;
Q.push(ljl[0].son[i]);
}
}
while(!Q.empty())
{
rg int now=Q.front();Q.pop();
for(rg int i=0;i<26;++i)
{
if(ljl[now].son[i])
{
ljl[ljl[now].son[i]].fail=ljl[ljl[now].fail].son[i];
Q.push(ljl[now].son[i]);
}
else ljl[now].son[i]=ljl[ljl[now].fail].son[i];
}
}
}
il int Query(string s)
{
rg int L=s.length();
int now=0,ans=0;
for(rg int i=0;i<L;++i)
{
rg int kk=s[i]-'a';
now=ljl[now].son[kk];
for(rg int tt=now;tt&&ljl[tt].end!=-1;tt=ljl[tt].fail)
{
ans+=ljl[tt].end;
ljl[tt].end=-1;
}
}
return ans;
}
int main()
{
freopen("s.in","r",stdin);
n=read();
for(rg int i=1;i<=n;++i)
cin>>s,Insert();
ljl[0].fail=0;
get_fail();
cin>>s;
printf("%d\n",Query(s));
return 0;
}
PS:我数组开大了RE了好久……
哪怕人间是炼狱,梦想永远是天堂
继续走下去吧,理想永远都年轻,花儿一定会再次盛开