比赛 |
欢乐水题赛 |
评测结果 |
AAAAAA |
题目名称 |
AC自动机 |
最终得分 |
100 |
用户昵称 |
Satoshi |
运行时间 |
0.111 s |
代码语言 |
C++ |
内存使用 |
0.26 MiB |
提交时间 |
2015-04-24 15:51:06 |
显示代码纯文本
#include <fstream>
#include <string>
#include <vector>
#include <queue>
#include <string.h>
using namespace std;
ifstream in("ACautomata.in");
ofstream out("ACautomata.out");
class node
{
public:
int n;
int back;
int flag;
vector<int> F;
node()
{
F.resize(26,0);//改变数组大小
n=0;
flag=0;//单词末尾
back=0;//失败指针
}
void insert(int n,int d)
{
F[n]=d;
}
int find(int n){return F[n];}
};
class point
{
public:
string txt;
int ans;
point(string a)
{
txt=a;
ans=0;
}
};
vector<node>T;
vector<point> ans;
void insert(string S)//插入字符串, 构造字典树
{
int r=0;
int i;
for(i=0;i<S.size();i++)
{
int v=S[i]-'a';
int t=T[r].find(v);
if(t==0)
{
T.push_back(node());
T[r].insert(v,T.size()-1);
r=T.size()-1;
T[r].n=v;
}
else
{
r=t;
}
}
T[r].flag=ans.size()-1;
}
void build()
{
int i;
T[0].back=0;
queue<int> q;
for(i=0;i<26;i++)
{
int r=T[0].find(i);
if(r)
{
T[r].back=0;
q.push(r);
}
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(i=0;i<26;i++)
{
int v=T[u].find(i);
if(v)
{
q.push(v);
int it=u,r=T[T[it].back].find(T[v].n);
while(r==0&&it!=0)
{
it=T[it].back;
r=T[T[it].back].find(T[v].n);
}
T[v].back=r;
}
}
}
}
void pluse(int i)
{
while(i!=0)
{
if(T[i].flag!=0)
{
ans[T[i].flag].ans++;
}
i=T[i].back;
}
}
void core(string &S)
{
int i;
int it=0;
for(i=0;i<S.size();i++)
{
int u=S[i]-'a';
int r=T[it].find(u);
while(!r&&it)
{
it=T[it].back;
r=T[it].find(u);
}
if(r==0)
{
it=0;
continue;
}
it=r;
pluse(r);
}
return ;
}
int main()
{
int n,i;
in>>n;
T.push_back(node());
T[0].n=0;
ans.push_back(point("@"));
//out<<n<<endl;
for(i=1;i<=n;i++)
{
string s;
in>>s;
//out<<s<<endl;
ans.push_back(point(s));
insert(s);
}
build();
string S;
in>>S;
core(S);
for(i=1;i<ans.size();i++)out<<ans[i].txt<<' '<<ans[i].ans<<endl;
return 0;
}