比赛 欢乐水题赛 评测结果 AAAAAA
题目名称 AC自动机 最终得分 100
用户昵称 mikumikumi 运行时间 0.517 s
代码语言 C++ 内存使用 0.96 MiB
提交时间 2015-04-24 15:04:42
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<deque>
#include<string>
using namespace std;
int n,ans[100001],shit[27]={0};
class miku
{
public:
	int flag;
	int link[27];
	int fail;
	miku()
	{
		flag=-1;
		fail=-1;
		for(int i=0;i<26;i++)
			link[i]=-1;
	}	
};
deque<miku> q;
string b;
int step(int x,int y)
{
	while(true)
	{
		if(q[x].link[y]!=-1) return q[x].link[y];
		else if(x==0) return 0;
		x=q[x].fail;
	}
}
int tire(string a,int i)
{
	int len=a.length(),root=0;
	for(int j=0;j<len;j++)
	{
		int t=a[j]-'a';
		if(q[root].link[t]==-1)
		{
			miku x;
			//if(root==0)
			//	x.fail=0;
			//else
			//{
			//	x.fail=step(q[root].fail,t);
			//}
			q[root].link[t]=q.size();
			q.push_back(x);
		}
		root=q[root].link[t];
		if(j==len-1)
			shit[t]=1;
	}
	q[root].flag=i;
	
	return 0;
}
int makefail()
{
	int root=0;
	deque<int> Q;
	q[0].fail=0;
	Q.push_back(0);
	while(!Q.empty())
	{
		int x=Q.front();
		Q.pop_front();
		for(int i=0;i<26;i++)
		{
			if(q[x].link[i]!=-1)
			{
				if(x==0) q[q[x].link[i]].fail=0;
				else
				{
					q[q[x].link[i]].fail=step(q[x].fail,i);
				}
				Q.push_back(q[x].link[i]);
			}
		}
	}
	return 0;
}
int main()
{
	freopen("ACautomata.in","r",stdin);
	freopen("ACautomata.out","w",stdout);
	scanf("%d",&n);
	miku x;
	x.fail=0;
	q.push_back(x);
	string a[100001];
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		tire(a[i],i);
	}
	makefail();
	cin>>b;
	int len=b.length();
	int root=0;
	int hs[100001];
	for(int i=0;i<26;i++)
		if(q[root].link[i]!=-1)
			hs[q[root].link[i]]=1;
	for(int i=0;i<len;i++)
	{
		int t=b[i]-'a';
		if(q[root].link[t]!=-1)
			root=q[root].link[t];
		else
		   root=step(q[root].fail,t);
		//cout<<root<<endl;
			int fuck=root;
			if(shit[t]==1)
			{
			while(true)
			{
				if(fuck!=0)
				{
				if(q[fuck].flag!=-1)
				ans[q[fuck].flag]++;
				//cout<<q[fuck].fail<<endl;
				fuck=q[fuck].fail;
				}
				else
					break;
			}
			}
	}
	for(int i=1;i<=n;i++)
	{
		cout<<a[i]<<" "<<ans[i]<<endl;
	}
	/*for(int i=0;i<q.size();i++)
	{
		cout<<i<<" "<<q[i].flag<<" "<<q[i].fail<<endl;
		for(int j=0;j<26;j++)
		cout<<q[i].link[j]<<" ";
		cout<<endl;
	}*/
return 0;
}