Pagini recente » Cod sursa (job #2386050) | Cod sursa (job #2384377) | Cod sursa (job #337849) | Cod sursa (job #74426) | Cod sursa (job #3239455)
#include <fstream>
#include <queue>
#define int long long
using namespace std;
ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");
const int M = 1e6;
const int N = 100;
int rez[N + 1];
bool f[M + 1], viz[M + 1];
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 go_up (trie *root)
{
while (root->suff_link != nullptr)
{
if (root->nr == 1);
root->suff_link->dp += root->dp;
root = root->suff_link;
}
}
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)
f[root->suff_link->nr] = 1;
}
void dfs1 (trie *root)
{
for (int i = 0; i < 26; ++i)
if (root->children[i] != nullptr)
dfs1 (root->children[i]);
if (!f[root->nr])
pq.push(root), viz[root->nr] = 1;
}
void bfs1()
{
while (!pq.empty())
{
trie* aux = pq.front();
//cout << aux->nr << ' ' << aux->dp << '\n';
pq.pop();
if (aux->suff_link != nullptr)
{
aux->suff_link->dp += aux->dp;
if (!viz[aux->suff_link->nr])
pq.push (aux->suff_link), viz[aux->suff_link->nr] = 1;
}
}
}
void dfs2 (trie *root)
{
if (root->isleaf)
{
for (auto it : root->index)
rez[it] = root->dp;
}
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;
else
root = suff(root, ch), root->dp += 1;
}
}
signed 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);
dfs1 (root);
bfs1 ();
dfs2 (root);
for (int i = 1; i <= n; ++i)
cout << rez[i] << '\n';
return 0;
}