Pagini recente » Cod sursa (job #3304072) | Diferente pentru problema/dk intre reviziile 52 si 51 | Cod sursa (job #3344635) | Cod sursa (job #3329952) | Cod sursa (job #3357790)
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>
std::vector<int> ans(100, 0);
struct Trie {
private:
struct Vertex {
int next[26] = {0};
int fail = -1;
int output = -1;
Vertex() {
for (int &i : next) i = -1;
}
};
std::vector<Vertex> cont;
int &next(int node, char c) {
return cont[node].next[c - 'a'];
}
int &output(int node) {
return cont[node].output;
}
int &fail(int node) {
return cont[node].fail;
}
void push_links() {
std::queue<int> q;
for (int i = 0; i < 26; ++i) {
if (next(0, 'a' + i) != -1) {
int child = next(0, 'a' + i);
fail(child) = 0;
q.push(child);
} else {
next(0, 'a' + i) = 0;
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < 26; ++i) {
char c = 'a' + i;
int &v = next(u, c);
if (v != -1) {
fail(v) = next(fail(u), c);
output(v) = (output(fail(v)) != -1) ? output(fail(v)) : output(v);
q.push(v);
} else {
next(u, c) = next(fail(u), c);
}
}
}
}
public:
Trie() {
cont.emplace_back();
}
void add_word(const std::string &str, int idx) {
int node = 0;
for (char c : str) {
if (next(node, c) == -1) {
next(node, c) = cont.size();
cont.emplace_back();
}
node = next(node, c);
}
output(node) = idx;
}
void compute() {
fail(0) = 0;
push_links();
}
void advance(int &state, char c) {
state = next(state, c);
int temp = state;
while (temp != 0 && output(temp) != -1) {
ans[output(temp)]++;
temp = fail(temp);
}
}
};
int main() {
std::ifstream input("ahocorasick.in");
std::ofstream output("ahocorasick.out");
Trie trie;
std::string s;
int n;
input >> s >> n;
std::vector<std::string> words(n);
for (int i = 0; i < n; ++i) {
input >> words[i];
trie.add_word(words[i], i);
}
trie.compute();
int state = 0;
for (char c : s) {
trie.advance(state, c);
}
for (int i = 0; i < n; ++i) {
output << ans[i] << '\n';
}
return 0;
}