Pagini recente » Cod sursa (job #1339018) | Cod sursa (job #2327771) | Cod sursa (job #1937799) | Cod sursa (job #2760570) | Cod sursa (job #794029)
Cod sursa(job #794029)
#include <fstream>
#include <vector>
#include <cstring>
#define NM 100010
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct Trie
{
Trie *Fail;
int nr;
Trie *Sons[26];
vector<int> out;
Trie ()
{
Fail=0;
nr=0;
memset(Sons,0,sizeof(Sons));
}
} *T=new Trie();
int N,i;
string S,STR;
int ANS[NM];
int P,U;
void Insert (Trie *T, char *p, int i)
{
if ('a'>*p || *p>'z')
{
T->out.push_back(i);
return;
}
int next=*p-'a';
if (T->Sons[next])
Insert(T->Sons[next],++p,i);
else
{
T->Sons[next]=new Trie();
Insert(T->Sons[next],++p,i);
}
}
Trie *Q[NM];
Trie *CT,*R;
int main ()
{
getline(f,STR);
f >> N;
getline(f,S);
for (i=1; i<=N; i++)
{
getline(f,S);
Insert(T,&S[0],i);
}
Q[P=U=1]=T;
T->Fail=T;
while (P<=U)
{
CT=Q[P++];
for (i=0; i<26; i++)
if (CT->Sons[i])
{
for (R=CT->Fail; R!=T && R->Sons[i]==0; R=R->Fail);
if (R->Sons[i] && R->Sons[i]!=CT->Sons[i])
R=R->Sons[i];
CT->Sons[i]->Fail=R;
Q[++U]=CT->Sons[i];
}
}
T->Fail=0;
CT=T;
for (i=0; i<STR.size(); i++)
{
int next=STR[i]-'a';
for (;CT->Sons[next]==0 && CT!=T; CT=CT->Fail);
if (CT->Sons[next]) CT=CT->Sons[next];
++CT->nr;
}
for (i=U; i>=1; i--)
{
CT=Q[i];
if (CT->Fail) CT->Fail->nr+=CT->nr;
for (int j=0; j<CT->out.size(); j++)
ANS[CT->out[j]]=CT->nr;
}
for (i=1; i<=N; i++)
g << ANS[i] << '\n';
f.close();
g.close();
return 0;
}