Pagini recente » Cod sursa (job #2610243) | Cod sursa (job #1192315) | Cod sursa (job #2410444) | Cod sursa (job #1852982) | Cod sursa (job #2522130)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
class Trie {
private:
struct Node {
int exit, link, father;
char letter;
int next[26], tran[26];
vector<int> ends;
Node(int father = -1, char letter = '*') : father(father), letter(letter) {
exit = -1;
link = -1;
fill(begin(next), end(next), -1);
fill(begin(tran), end(tran), -1);
}
};
int n;
vector<Node> trie;
public:
Trie() : n(0), trie(1) {
trie[0].exit = 0;
}
void insert(string& str);
void lazy(int node);
vector<int> count(string& str);
int getLink(int node);
int getTran(int node, char chr);
};
void Trie::insert(string& str) {
int node = 0;
for (char chr : str) {
int code = chr - 'a';
if (trie[node].next[code] == -1) {
trie[node].next[code] = trie.size();
trie.emplace_back(node, chr);
}
node = trie[node].next[code];
}
trie[node].ends.push_back(n++);
}
int Trie::getLink(int node) {
if (trie[node].link == -1) {
if (!node || !trie[node].father)
trie[node].link = 0;
else
trie[node].link = getTran(getLink(trie[node].father), trie[node].letter);
}
return trie[node].link;
}
int Trie::getTran(int node, char chr) {
int code = chr - 'a';
if (trie[node].tran[code] == -1) {
if (trie[node].next[code] != -1)
trie[node].tran[code] = trie[node].next[code];
else
trie[node].tran[code] = (node ? getTran(getLink(node), chr) : 0);
}
return trie[node].tran[code];
}
void Trie::lazy(int node) {
if (trie[node].exit != -1)
return;
lazy(getLink(node));
trie[node].exit = (trie[getLink(node)].ends.empty() ? trie[getLink(node)].exit : getLink(node));
}
vector<int> Trie::count(string& str) {
vector<int> cnt(n);
int node = 0;
for (char chr : str) {
node = getTran(node, chr);
lazy(node);
int temp = node;
while (temp) {
for (int it : trie[temp].ends)
cnt[it]++;
temp = trie[temp].exit;
}
}
return cnt;
}
int main() {
string str; fin >> str;
int n; fin >> n;
Trie trie;
for (int i = 0; i < n; i++) {
string s; fin >> s;
trie.insert(s);
}
auto sol = trie.count(str);
for (int i = 0; i < n; i++)
fout << sol[i] << '\n';
return 0;
}