Pagini recente » Cod sursa (job #852688) | Cod sursa (job #1169450) | Cod sursa (job #1895179) | Cod sursa (job #2722923) | Cod sursa (job #2374035)
#include <bits/stdc++.h>
#define maxN 1000002
#define SIGMA 26
using namespace std;
FILE *fin = freopen("ahocorasick.in", "r", stdin);
FILE *fout = freopen("ahocorasick.out", "w", stdout);
char a[maxN], s[maxN / 10 + 2];
struct Trie
{
Trie* sons[SIGMA];
Trie* failLink, *outLink;
vector < int > WordId;
int cnt;
} nodes[maxN / 2];
Trie* T;
queue < Trie* > Q;
vector < Trie* > outQ;
int nodesCount = 0;
int frq[maxN / 10 + 2];
Trie* newTrie()
{
return &nodes[nodesCount++];
}
void Insert(Trie* node, char *w, int id)
{
if (*w == NULL)
{
node->WordId.push_back(id);
return ;
}
if (node->sons[*w - 'a'] == NULL)
node->sons[*w - 'a'] = newTrie();
Insert(node->sons[*w - 'a'], w + 1, id);
}
void goTo()
{
T->failLink = T->outLink = NULL;
for (int c = 0; c < SIGMA; ++ c)
if (T->sons[c] != NULL)
{
Q.push(T->sons[c]);
T->sons[c]->failLink = T;
}
}
void compFailLink()
{
outQ.push_back(T);
while (!Q.empty())
{
Trie* node = Q.front();
outQ.push_back(node);
Q.pop();
for (int c = 0; c < SIGMA; ++ c)
if (node->sons[c] != NULL)
{
Trie *fL = node->failLink;
while (fL != T && fL->sons[c] == NULL)
fL = fL->failLink;
if (fL->sons[c] != NULL)
node->sons[c]->failLink = fL->sons[c];
else
node->sons[c]->failLink = T;
Q.push(node->sons[c]);
}
}
}
void getSol()
{
int m = strlen(a);
Trie* node = T;
for (int i = 0; i < m; ++ i)
{
while (node != T && node->sons[a[i] - 'a'] == NULL)
node = node->failLink;
if (node->sons[a[i] - 'a'] != NULL)
node = node->sons[a[i] - 'a'];
++ node->cnt;
}
while (!outQ.empty())
{
node = outQ.back();
outQ.pop_back();
if (node->failLink != NULL)
node->failLink->cnt += node->cnt;
for (int id : node->WordId)
frq[id] += node->cnt;
}
}
int main()
{
int n;
scanf("%s", a);
scanf("%d\n", &n);
T = newTrie(); ///root
for (int i = 0; i < n; ++ i)
{
scanf("%s\n", &s);
Insert(T, s, i);
}
goTo();
compFailLink();
getSol();
for (int i = 0; i < n; ++ i)
printf("%d\n", frq[i]);
return 0;
}