[hdu2222] Keywords Search

Description

给定 (n) 个长度不超过 (50) 的由小写英文字母组成的单词准备查询,以及一篇长为 (m) 的文章,问:文中出现了多少个待查询的单词。多组数据。

Input

第一行一个整数 (T),表示数据组数;
对于每组数据,第一行一个整数 (n),接下去 (n) 行表示 (n) 个单词,最后一行输入一个字符串,表示文章。

Output

对于每组数据,输出一个数,表示文中出现了多少个待查询的单词。

Sample Input

1
5
she
he
say
shr
her
yasherhs

Sample Output

3

Hint

对于全部数据,(1le nle 10^4,1le mle 10^6)

题解

AC自动机模板题

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<bitset>
#include<vector>
#include<iomanip>
using namespace std;

const int Size=26,Maxn=500005;
struct Trie{
	int son[Maxn][Size],fail[Maxn],cnt[Maxn];
/*	son[i][j]存放 父节点的下标为i 的子节点字符为j的下标
	fail[i]下标为i的节点如果失配放回的下标
	cnt[i]从根节点到下标为i的节点所构成的模式串的个数
*/	int id;
	Trie(){id=0;}//构造函数
	int Newnode()//新建一个节点
	{
		for(int i=0;i<Size;++i) son[id][i]=-1;
		cnt[id]=0;
		return id++;
	}
	void Init()//初始化
	{
		id=0,Newnode();
	}
	void Insert(char s[])//把模式串s插入到Trie树
	{
		int l=strlen(s),now=0,k;
		for(int i=0;i<l;++i)
		{
			k=s[i]-'a';
			if(son[now][k]==-1) son[now][k]=Newnode();
			now=son[now][k];
		}
		++cnt[now];
	}
	queue<int> Q;
	void Build()//构建Fail指针
	{
		while(!Q.empty()) Q.pop();
		fail[0]=0;
		for(int i=0;i<Size;++i)
			if(son[0][i]==-1) son[0][i]=0;
			else
			{
				fail[son[0][i]]=0;
				Q.push(son[0][i]);
			}
		int now;
		while(!Q.empty())
		{
			now=Q.front(); Q.pop();
			for(int i=0;i<Size;++i)
				if(son[now][i]==-1) son[now][i]=son[fail[now]][i];
				else
				{
					fail[son[now][i]]=son[fail[now]][i];
					Q.push(son[now][i]);
				}
		}
	}
	int Query(char s[])//文本串来匹配
	{
		int len=strlen(s),now=0,Res=0;
		for(int i=0;i<len;++i)
		{
			now=son[now][s[i]-'a'];
			int tmp=now;
			while((tmp)&&(cnt[tmp]!=-1))
			{
				Res+=cnt[tmp],
				cnt[tmp]=-1,
				tmp=fail[tmp];
			}
		}
		return Res;
	}
}AC;
char s[Maxn+Maxn];

int main()
{
	int T,n;
	for(scanf("%d",&T);T;--T)
	{
		scanf("%d",&n);
		AC.Init();
		for(int i=1;i<=n;++i)
		{
			scanf("%s",s);
			AC.Insert(s);
		}
		AC.Build();
		scanf("%s",s);
		printf("%d
",AC.Query(s));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/hihocoder/p/12818314.html