Pagini recente » Cod sursa (job #2535231) | Cod sursa (job #2850951) | Cod sursa (job #892268) | Cod sursa (job #3030991) | Cod sursa (job #1981550)
#include <bits/stdc++.h>
using namespace std;
constexpr int nmax = 1000005;
constexpr int sigma = 26;
char B[nmax];
char A[nmax];
int num, n, m, cnt;
struct AC {
AC *next[sigma];
AC *fail;
vector<AC *> v;
int cnt;
AC() : cnt(0) {
for (int i = 0; i < sigma; i++) {
next[i] = nullptr;
}
fail = nullptr;
}
int ord(char c) {
assert(c >= 'a' && c <= 'z');
return c - 'a';
}
AC *add(const char *S) {
if (*S == 0) {
return this;
}
int x = ord(*S);
if (next[x] == nullptr) {
next[x] = new AC;
}
return next[x]->add(S + 1);
}
AC *nextNode(char c, AC *root) {
int x = ord(c);
AC *tmp = this;
while (tmp && tmp->next[x] == nullptr) tmp = tmp->fail;
if (!tmp) return root;
return tmp->next[x];
}
};
void backlinks(AC *root) {
queue<AC *> q;
q.push(root);
while (!q.empty()) {
AC *front = q.front();
q.pop();
for (int i = 0; i < sigma; i++) {
if (front->next[i] == nullptr) continue;
AC *tmp = front->fail;
while (tmp && tmp->next[i] == nullptr) {
tmp = tmp->fail;
}
if (tmp == nullptr) {
front->next[i]->fail = root;
root->v.push_back(front->next[i]);
} else {
front->next[i]->fail = tmp->next[i];
tmp->next[i]->v.push_back(front->next[i]);
}
q.push(front->next[i]);
}
}
}
void df(AC *x) {
for (AC *y : x->v) {
df(y);
x->cnt += y->cnt;
}
}
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
scanf("%s", B);
scanf("%d", &num);
m = strlen(B);
AC *ac = new AC;
vector<AC *> words(num, nullptr);
for (int i = 0; i < num; i++) {
scanf("%s", A);
words[i] = ac->add(A);
}
backlinks(ac);
AC *tmp = ac;
for (int i = 0; i < m; i++) {
tmp = tmp->nextNode(B[i], ac);
tmp->cnt++;
}
df(ac);
for (int i = 0; i < num; i++) {
printf("%d\n", words[i]->cnt);
}
return 0;
}