Pagini recente » Monitorul de evaluare | Cod sursa (job #2927332) | Cod sursa (job #599850) | Cod sursa (job #2650236) | Cod sursa (job #3348521)
#include <bits/stdc++.h>
using namespace std;
const int K = 26;
struct AHO {
int nr = 0;
vector<int> posS;
struct Node {
int p = 0, cnt = 0;
vector<int> nxt;
Node() {
nxt.resize(K, -1);
}
};
vector<Node> trie;
AHO() {
trie.emplace_back();
}
void add(string s) {
int pos = 0;
for (auto ch : s) {
int i = ch - 'a';
if (trie[pos].nxt[i] == -1) {
trie[pos].nxt[i] = trie.size();
trie.emplace_back();
}
pos = trie[pos].nxt[i];
}
posS.push_back(pos);
nr ++;
}
vector<int> ord;
void build() {
queue<int> q;
for (int c = 0; c < K; c ++) {
if (trie[0].nxt[c] != -1) {
trie[trie[0].nxt[c]].p = 0;
q.push(trie[0].nxt[c]);
} else {
trie[0].nxt[c] = 0;
}
}
while (!q.empty()) {
auto x = q.front();
q.pop();
ord.push_back(x);
for (int c = 0; c < K; c ++) {
int v = trie[x].nxt[c];
if (v != -1) {
trie[v].p = trie[trie[x].p].nxt[c];
q.push(v);
} else {
trie[x].nxt[c] = trie[trie[x].p].nxt[c];
}
}
}
}
vector<int> query(string s) {
int pos = 0;
vector<int> ans(nr, 0);
for (auto ch : s) {
int i = ch - 'a';
pos = trie[pos].nxt[i];
trie[pos].cnt ++;
}
reverse(ord.begin(), ord.end());
for (auto i : ord) {
trie[trie[i].p].cnt += trie[i].cnt;
}
for (int i = 0; i < nr; i ++) {
ans[i] = trie[posS[i]].cnt;
}
return ans;
}
};
signed main() {
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
int n;
string a;
cin >> a >> n;
vector<string> s(n);
for (auto &i : s) {
cin >> i;
}
AHO ds;
for (auto i : s) {
ds.add(i);
}
ds.build();
auto x = ds.query(a);
for (auto i : x) {
cout << i << '\n';
}
}