Pagini recente » Cod sursa (job #1328955) | Cod sursa (job #2808024) | Cod sursa (job #2839848) | Cod sursa (job #1603817) | Cod sursa (job #2784578)
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <cassert>
#include <algorithm>
using namespace std;
const int N = 23456;
int n;
int y;
int kids[N][26];
int fl[N];
int cnt[N];
vector<int> indi[N];
string pattern;
int sol[123];
int main() {
freopen ("ahocorasick.in", "r", stdin);
freopen ("ahocorasick.out", "w", stdout);
y++;
cin >> pattern >> n;
for (int i = 1; i <= n; i++) {
string s;
cin >> s;
int cur = 1;
for (auto &ch : s) {
int x = ch - 'a';
if (!kids[cur][x]) {
kids[cur][x] = ++y;
}
cur = kids[cur][x];
}
indi[cur].push_back(i);
assert(y + 1 < N);
}
queue<int> q;
q.push(1);
fl[1] = 1;
vector<int> ord;
while (!q.empty()) {
int a = q.front();
ord.push_back(a);
q.pop();
for (int i = 0; i < 26; i++) {
if (kids[a][i]) {
int acum = fl[a];
while (acum > 1 && !kids[acum][i]) {
acum = fl[acum];
}
if (kids[acum][i] && a != 1) {
acum = kids[acum][i];
}
fl[kids[a][i]] = acum;
q.push(kids[a][i]);
}
}
}
int cur = 1;
for (auto &ch : pattern) {
int x = ch - 'a';
while (cur && !kids[cur][x]) {
cur = fl[cur];
}
if (kids[cur][x]) {
cur = kids[cur][x];
}
cnt[cur]++;
}
reverse(ord.begin(), ord.end());
for (auto &i : ord) {
cnt[fl[i]] += cnt[i];
for (auto &j : indi[i]) {
sol[j] += cnt[i];
}
}
for (int i = 1; i <= n; i++) {
cout << sol[i] << "\n";
}
return 0;
}