Pagini recente » Cod sursa (job #1770844) | Monitorul de evaluare | Cod sursa (job #189823) | Cod sursa (job #219083) | Cod sursa (job #3303395)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int SIGMA = 26, NMAX = 2e5;
int n, ans[NMAX];
struct AhoCorasick
{
struct TrieNode
{
TrieNode *children[SIGMA], *fail_link;
int visited = 0;
vector<int> ending_words;
TrieNode() { fill(children, children + SIGMA, nullptr); }
};
TrieNode *root = new TrieNode;
vector<TrieNode*> BFS_order;
void insert_word(const string &word, int idx)
{
TrieNode *node = root;
for(char ch : word)
{
if(node->children[ch - 'a'] == nullptr)
node->children[ch - 'a'] = new TrieNode;
node = node->children[ch - 'a'];
}
node->ending_words.push_back(idx);
}
void build_automaton()
{
queue<TrieNode*> q;
root->fail_link = root;
q.push(root);
while(!q.empty())
{
TrieNode *node = q.front();
q.pop();
BFS_order.push_back(node);
for(char ch = 'a'; ch <= 'z'; ch++)
{
TrieNode *child = node->children[ch - 'a'];
if(child == nullptr)
continue;
TrieNode *fall_back = node->fail_link;
while(fall_back != root && fall_back->children[ch - 'a'] == nullptr)
fall_back = fall_back->fail_link;
if(fall_back->children[ch - 'a'] != nullptr && fall_back->children[ch - 'a'] != child)
child->fail_link = fall_back->children[ch - 'a'];
else
child->fail_link = root;
q.push(child);
}
}
}
void search_text(const string &text)
{
TrieNode *node = root;
for(char ch : text)
{
while(node != root && node->children[ch - 'a'] == nullptr)
node = node->fail_link;
if(node->children[ch - 'a'] != nullptr)
node = node->children[ch - 'a'];
node->visited++;
}
reverse(BFS_order.begin(), BFS_order.end());
for(TrieNode *node : BFS_order)
{
for(int idx : node->ending_words)
ans[idx] += node->visited;
node->fail_link->visited += node->visited;
}
}
};
AhoCorasick aho_corasick;
int main()
{
string text;
fin >> text >> n;
for(int i = 0; i < n; i++)
{
string word;
fin >> word;
aho_corasick.insert_word(word, i);
}
aho_corasick.build_automaton();
aho_corasick.search_text(text);
for(int i = 0; i < n; i++)
fout << ans[i] << "\n";
fin.close();
fout.close();
return 0;
}