Pagini recente » Cod sursa (job #1198469) | Cod sursa (job #349931) | Cod sursa (job #7153) | Cod sursa (job #366618) | Cod sursa (job #3228645)
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("sse,avx,fma,avx2,bmi,bmi2,lzcnt,popcnt")
using namespace std;
using ll = long long;
using ld = long double;
struct node {
unordered_map<char, node *> forward;
node *suffix = NULL, *output = NULL;
bool terminal = false;
int word_index;
void insert(string &p, int wi, int index) {
if (index == p.size()) {
terminal = true, word_index = wi;
return;
}
if (!forward.count(p[index]))
forward[p[index]] = new node;
forward[p[index]]->insert(p, wi, index + 1);
}
// assume this is called on root
void compute_suffix_links() {
queue<node *> q;
for (auto [c, neigh] : forward)
q.push(neigh), neigh->suffix = this;
while (!q.empty()) {
auto curr = q.front();
q.pop();
for (auto [c, neigh] : curr->forward) {
q.push(neigh);
auto try_suff = curr->suffix;
while (try_suff != this && try_suff->forward.count(c) == 0) {
try_suff = try_suff->suffix;
}
neigh->suffix = (try_suff->forward.count(c) ? try_suff->forward[c] : this);
neigh->output = (neigh->suffix->terminal ? neigh->suffix : neigh->suffix->output);
}
}
}
node *next_node(char c) {
if (forward.count(c))
return forward[c];
if (suffix == NULL)
return this;
return suffix->next_node(c);
}
void count_occurences(vector<int> &v) {
if (terminal)
++v[word_index];
if (output)
output->count_occurences(v);
}
~node() {
for (auto [_, neigh] : forward)
delete neigh;
}
};
void solve() {
string text;
int n;
cin >> text >> n;
vector<string> patterns(n);
for (auto &p : patterns)
cin >> p;
auto root = new node;
for (int i = 0; i < n; ++i)
root->insert(patterns[i], i, 0);
root->compute_suffix_links();
vector<int> ans(n, 0);
auto curr = root;
for (char c : text) {
curr = curr->next_node(c);
curr->count_occurences(ans);
}
delete root;
for (auto x : ans)
cout << x << '\n';
}
int main() {
#ifndef ONLINE_JUDGE
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
#endif
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}