Pagini recente » Rating Rosioru Alin (Rosioru) | Cod sursa (job #1260487) | Monitorul de evaluare | Cod sursa (job #970848) | Cod sursa (job #1553516)
#include <bits/stdc++.h>
using namespace std;
const int sigma = 'z' - 'a' + 1;
const int Nmax = 100 + 10;
const int Lenght = 1000000 + 10;
struct Trie
{
int nr;
Trie *prv;
Trie *son[sigma];
Trie *phi;
Trie()
{
prv = NULL;
for (int i = 0; i < sigma; ++i) son[i] = NULL;
nr = 0;
};
};
int n , i , last;
string s , sir;
Trie *term[Nmax] , *root;
pair < Trie* , char > q[Lenght];
Trie *add(Trie *node , int p)
{
if (p == s.size()) return node;
int ch = s[p] - 'a';
if (node -> son[ch] == NULL)
node -> son[ch] = new Trie,
node -> son[ch] -> prv = node;
return add(node -> son[ch] , p + 1);
}
void makePhi()
{
Trie *crt , *node; char ch;
root -> phi = root; root -> prv = root; int i;
q[++last] = {root , 0};
for (int j = 0; j < sigma; ++j)
if (root -> son[j] != NULL)
{
root -> son[j] -> phi = root;
q[++last] = {root -> son[j] , j};
}
for (i = 2; i <= last; i++)
{
tie(node , ch) = q[i];
if (node -> prv != root)
{
crt = node -> prv -> phi;
while (crt != root && crt -> son[ch] == NULL)
crt = crt -> phi;
if (crt -> son[ch] != NULL) crt = crt -> son[ch];
node -> phi = crt;
}
for (int j = 0; j < sigma; ++j)
if (node -> son[j] != NULL)
q[++last] = {node -> son[j],j};
}
}
void makeSol()
{
Trie *node = root;
for (int i = 0; i < sir.size(); ++i)
{
char ch = sir[i] - 'a';
while (node != root && node -> son[ch] == NULL)
node = node -> phi;
if (node -> son[ch] != NULL) node = node -> son[ch];
node -> nr++;
}
for (int i = last; i ; --i)
q[i].first -> phi -> nr += q[i].first -> nr;
}
int main()
{
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
fin >> sir;
fin >> n; root = new Trie;
for (i = 1; i <= n; ++i)
{
fin >> s;
term[i] = add(root , 0);
}
makePhi();
makeSol();
for (i = 1; i <= n; ++i)
fout << term[i] -> nr << '\n';
return 0;
}