Pagini recente » Cod sursa (job #280255) | Cod sursa (job #1916333) | Cod sursa (job #1406868) | Cod sursa (job #1850171) | Cod sursa (job #3239458)
#include <fstream>
#include <queue>
#include <algorithm>
using namespace std;
ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");
const int M = 1e6;
const int N = 100;
int rez[N + 1];
bool viz[M + 1];
int val[M + 1];
vector <int> g[M + 1], v;
struct trie
{
int dp, nr;
vector <int> index;
bool isleaf;
trie *children[26], *suff_link;
trie (int x = 0)
{
dp = 0;
nr = x;
index.clear();
isleaf = false;
suff_link = nullptr;
for (int i = 0; i < 26; ++i)
children[i] = nullptr;
}
};
trie *root = new trie();
string a, s;
queue <trie*> pq;
int n, poz, t;
void add_word (trie *root, string s)
{
for (auto it : s)
{
int ch = it - 'a';
if (root->children[ch] == nullptr)
root->children[ch] = new trie(++t);
root = root->children[ch];
}
root->isleaf = 1;
root->index.push_back(poz);
}
trie* suff (trie *aux, int poz)
{
if (aux == root && aux->children[poz] != nullptr)
return aux->children[poz];
while (aux != root)
{
aux = aux->suff_link;
if (aux->children[poz] != nullptr)
return aux->children[poz];
}
return aux;
}
void bfs (trie *root)
{
queue <trie*> q;
for (int i = 0; i < 26; ++i)
if (root->children[i] != nullptr)
root->children[i]->suff_link = root, q.push(root->children[i]);
while (!q.empty())
{
trie *aux = q.front();
q.pop();
for (int i = 0; i < 26; ++i)
if (aux->children[i] != nullptr)
{
aux->children[i]->suff_link = suff(aux, i);
q.push(aux->children[i]);
}
}
}
void dfs (trie *root)
{
for (int i = 0; i < 26; ++i)
if (root->children[i] != nullptr)
{
dfs (root->children[i]);
}
if (root->suff_link != nullptr)
g[root->nr].push_back(root->suff_link->nr);
}
void dfs1 (int node)
{
viz[node] = 1;
for (auto it : g[node])
if (!viz[it])
dfs1 (it);
v.push_back(node);
}
void dfs2 (trie *root)
{
if (root->isleaf)
{
for (auto it : root->index)
rez[it] = val[root->nr];
}
for (int i = 0; i < 26; ++i)
if (root->children[i] != nullptr)
dfs2 (root->children[i]);
}
void solve (trie *root)
{
for (auto it : s)
{
int ch = it - 'a';
if (root->children[ch] != nullptr)
root = root->children[ch], root->dp += 1, val[root->nr]++;
else
root = suff(root, ch), root->dp += 1, val[root->nr]++;
}
}
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(0);
cin >> s >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a;
++poz;
add_word(root, a);
}
bfs(root);
solve(root);
dfs (root);
for (int i = 1; i <= t; ++i)
if (!viz[i])
dfs1(i);
reverse (v.begin(), v.end());
for (auto it : v)
for (auto it1 : g[it])
val[it1] += val[it];
dfs2 (root);
for (int i = 1; i <= n; ++i)
cout << rez[i] << '\n';
return 0;
}