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
",Query(s));
	return 0;
}

PS:我数组开大了RE了好久……

原文地址:https://www.cnblogs.com/cjoierljl/p/9359165.html