Pagini recente » Cod sursa (job #1351588) | Cod sursa (job #2464297) | Cod sursa (job #894488) | Cod sursa (job #2494510) | Cod sursa (job #3149412)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
struct AhoCorasick {
struct Node {
int fail_link;
map<char, int> link;
int cnt;
Node() {}
Node(int fail_link, int cnt) : fail_link(fail_link), cnt(cnt){}
};
const Node ROT = Node(-1, 0);
vector<Node> T;
vector<int> q;
vector<int> order;
vector<int> ptr;
int nodes = 1;
AhoCorasick() {
Init();
}
void Init() {
T.clear();
T.emplace_back(ROT);
}
// Adds a word to trie and returns the end node
int Add(const string &s) {
int node = 0, idx = 0;
for(const auto &c : s) {
idx++;
auto &nxt = T[node].link[c];
if(nxt == 0) {
nxt = nodes++;
T.emplace_back(Node(0, 0));
}
node = nxt;
}
ptr.emplace_back(node);
return node;
}
// Advances from a node with a character (like an automaton)
int Go(int node, char c) {
while(node != -1 && !T[node].link.count(c)) {
node = T[node].fail_link;
}
return (node == -1 ? 0 : T[node].link[c]);
}
// Builds links
void Build() {
T[0].fail_link = -1, q.push_back(0);
for(int i = 0; i < (int)q.size(); ++i) {
int node = q[i];
order.emplace_back(node);
for (auto [c, vec] : T[node].link) {
T[vec].fail_link = Go(T[node].fail_link, c), q.push_back(vec);
}
}
}
void solve(const string &s) {
int u = 0;
for(const auto &it: s) {
while(!T[u].link.count(it) && u) {
u = T[u].fail_link;
}
if(T[u].link.count(it)) {
u = T[u].link[it];
}
T[u].cnt += 1;
}
reverse(order.begin(), order.end());
for(const auto &it: order) if(it != 0) {
T[T[it].fail_link].cnt += T[it].cnt;
}
for(const auto &it: ptr) {
fout << T[it].cnt << '\n';
}
}
};
int main() {
string s;
fin >> s;
int n;
fin >> n;
AhoCorasick ds;
for(int i = 0; i < n; i++) {
string t;
fin >> t;
ds.Add(t);
}
ds.Build();
ds.solve(s);
return 0;
}