暑假- ac自动机-(A - Keywords Search)

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int MAXM=500010;
const int MAXN=1000010;
char str[MAXN];
struct trie
{
	int root,trieN;
	int child[MAXM][26],value[MAXM],fail[MAXM];
	int NewTrie()
	{
		value[trieN]=0;
		memset(child[trieN],-1,sizeof(child[trieN]));
		return trieN++;
	}
	void init()
	{
		trieN=0;
		root=NewTrie();
	}
	void Insert(char s[])
	{
		int x=root;
		for(int i=0;s[i];i++)
		{
			if(child[x][s[i]-'a']==-1)
			{
				child[x][s[i]-'a']=NewTrie();
			}
			x=child[x][s[i]-'a'];
		}
		value[x]++;
	}
	void Build()
	{
		int x;
		queue<int> q;
		fail[root]=root;
		for(int i=0;i<26;i++)
		{
			if(child[root][i]==-1)
			{
				child[root][i]=root;
			}
			else
			{
				fail[child[root][i]]=root;
				q.push(child[root][i]);
			}
		}
		while(!q.empty())
		{
			x=q.front();q.pop();
			for(int i=0;i<26;i++)
			{
				if(child[x][i]==-1)
				{
					child[x][i]=child[fail[x]][i];
				}
				else
				{
					fail[child[x][i]]=child[fail[x]][i];
					q.push(child[x][i]);
				}
			}
		}
	}	
	int query(char s[])
	{
		int sum=0;
		int x=root,temp;
		for(int i=0;s[i];i++)
		{
			temp=x=child[x][s[i]-'a'];
			while(temp!=root)
			{
				sum+=value[temp];
				value[temp]=0;
				temp=fail[temp];
			}
		}
		return sum;
	}
}ac;
int main()
{
	int t,n;
	cin>>t;
	while(t--)
	{
		cin>>n;
		char ch[55];
		ac.init();
		for(int i=0;i<n;i++)
		{
			cin>>ch;
			ac.Insert(ch);
		}
		ac.Build();
		cin>>str;
		cout<<ac.query(str)<<endl;
	}
	return 0;
}
			
	
		

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值