Pagini recente » Cod sursa (job #1008358) | Cod sursa (job #1220506) | Cod sursa (job #2549605) | Cod sursa (job #1572902) | Cod sursa (job #3235050)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// #define int ll
#define endl '\n'
#define pb push_back
using pi = array<int, 2>;
const int SIGMA = 26;
struct Node {
bool vis = false;
int parent_ch = -1, appeared = 0;
vector<int> exit_ids;
Node *parent = nullptr, *link = nullptr;
vector<Node*> rev_links;
array<Node*, SIGMA> ch{};
Node(Node *parent, int parent_ch) {
this->parent = parent;
this->parent_ch = parent_ch;
}
Node() { // root
link = this;
for (int i = 0; i < SIGMA; ++i) {
ch[i] = new Node(this, i);
ch[i]->link = this;
}
}
void add(int id, string& s, int ptr = 0) {
if (ptr == (int)s.size()) {
exit_ids.pb(id);
return;
}
int idx = s[ptr] - 'a';
if (ch[idx] == nullptr) {
ch[idx] = new Node(this, idx);
}
ch[idx]->add(id, s, ptr + 1);
}
void compute_links() {
if (link == nullptr) {
link = parent->link;
while (link->ch[parent_ch] == nullptr) {
link->compute_links();
link = link->link;
}
link = link->ch[parent_ch];
}
link->rev_links.pb(this);
for (auto node : ch) {
if (node == nullptr) continue;
node->compute_links();
}
}
void dfs(vector<int>& ans) {
if (vis) return;
vis = true;
for (auto node : rev_links) {
node->dfs(ans);
}
link->appeared += appeared;
for (auto node : ch) {
if (node == nullptr) continue;
node->dfs(ans);
}
for (int i : exit_ids) {
ans[i] = appeared;
}
}
};
int32_t main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
string a;
int n;
cin >> a >> n;
Node aho;
for (int i = 0; i < n; ++i) {
string s;
cin >> s;
aho.add(i, s);
}
aho.compute_links();
Node* node = &aho;
for (int i = 0; i < (int)a.size(); ++i) {
int idx = a[i] - 'a';
while (node->ch[idx] == nullptr) {
node = node->link;
}
node = node->ch[idx];
++node->appeared;
}
vector<int> ans(n);
aho.dfs(ans);
for (int i = 0; i < n; ++i) {
cout << ans[i] << endl;
}
}