比赛 |
欢乐水题赛 |
评测结果 |
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;
}