Pagini recente » Cod sursa (job #863730) | Cod sursa (job #2815122) | Cod sursa (job #1534500) | Cod sursa (job #3039899) | Cod sursa (job #2468413)
#include <bits/stdc++.h>
#define nmax 1000005
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct trie
{
trie *next[26];
trie *suf;
int fv;
trie()
{
this -> suf = NULL;
this -> fv = 0;
memset(this -> next, NULL, sizeof(this -> next));
}
};
trie *root = new trie();
trie* ans[nmax];
void add(trie *nod, string &c, const int index, int i, const int len)
{
if (i == len)
{
ans[index] = nod;
return;
}
int next_letter = c[i] - 'a';
if (nod -> next[next_letter] == nullptr)
nod -> next[next_letter] = new trie();
add(nod -> next[next_letter], c, index, i + 1, len);
}
vector <trie*> fin;
void create_links()
{
queue <trie*> coada;
coada.push(root);
while (!coada.empty())
{
trie *nod = coada.front();
coada.pop();
for (int i = 0; i < 26; ++ i)
if (nod -> next[i] != nullptr)
{
trie *now, *sufix;
now = nod -> next[i];
sufix = nod -> suf;
fin.push_back(now);
while (sufix != root && sufix -> next[i] == nullptr)
sufix = sufix -> suf;
if (sufix -> next[i] != nullptr && sufix -> next[i] != now) // primul nivel
now -> suf = sufix -> next[i];
else
now -> suf = root;
coada.push(now);
}
}
}
void antibfs()
{
for (int i = fin.size() - 1; i >= 0; i --)
fin[i] -> suf -> fv += fin[i] -> fv;
}
int main()
{
string s;
f >> s;
int n;
f >> n;
root -> suf = root;
for (int i = 1; i <= n; ++ i)
{
string c;
f >> c;
int len = c.length();
add(root, c, i, 0, len);
}
create_links();
trie *aux = root;
for (auto c : s)
{
int next_letter = c - 'a';
while (aux != root && aux -> next[next_letter] == nullptr)
aux = aux -> suf;
if (aux -> next[next_letter] != nullptr) // nu e radacina
{
aux = aux -> next[next_letter];
aux -> fv ++;
}
}
antibfs();
for (int i = 1; i <= n; ++ i)
g << ans[i] -> fv << '\n';
}