Pagini recente » Cod sursa (job #2221244) | Cod sursa (job #608009) | Cod sursa (job #357468) | Cod sursa (job #2279898) | Cod sursa (job #1736707)
#include <bits/stdc++.h>
using namespace std;
struct AhoCorasick {
struct Node {
int link;
map<char, int> leg;
};
vector<Node> T;
int root = 0, nodes = 1;
AhoCorasick(int sz) {
T.resize(sz);
}
// Adds a word to trie and returns the end node
int AddWord(const string &word) {
int node = root;
for(auto c : word) {
auto &nxt = T[node].leg[c];
if(nxt == 0)
nxt = nodes++;
node = nxt;
}
return node;
}
// Advances from a node with a character (like an automaton)
int Advance(int node, char chr) {
while(node != -1 && T[node].leg.count(chr) == 0)
node = T[node].link;
if(node == -1)
return root;
return T[node].leg[chr];
}
// Builds links
void BuildLinks() {
queue<int> Q;
Q.push(root);
T[root].link = -1;
while(!Q.empty()) {
int node = Q.front();
Q.pop();
for(auto &p : T[node].leg) {
int vec = p.second;
char chr = p.first;
T[vec].link = Advance(T[node].link, chr);
Q.push(vec);
}
}
}
};
AhoCorasick aho(1000005);
vector<int> occurences;
void SolveFor(string text) {
occurences.resize(aho.nodes);
int node = aho.root;
for(auto c : text) {
node = aho.Advance(node, c);
occurences[node] += 1;
}
vector<int> degree(aho.nodes);
for(int node = 1; node < aho.nodes; ++node) {
degree[aho.T[node].link] += 1;
}
queue<int> Q;
for(int node = 0; node < aho.nodes; ++node) {
if(degree[node] == 0)
Q.push(node);
}
while(!Q.empty()) {
int node = Q.front();
int link = aho.T[node].link;
Q.pop();
if(link == -1) continue;
occurences[link] += occurences[node];
if(--degree[link] == 0) {
Q.push(link);
}
}
}
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
string text, word;
cin >> text;
int n;
cin >> n;
vector<int> endNode(n);
for(int i = 0; i < n; ++i) {
cin >> word;
endNode[i] = aho.AddWord(word);
}
aho.BuildLinks();
SolveFor(text);
for(int i = 0; i < n; ++i)
cout << occurences[endNode[i]] << "\n";
return 0;
}