Pagini recente » Cod sursa (job #377435) | Cod sursa (job #17154) | Infoarena Monthly 2014 - Runda 3 | Cod sursa (job #2900618) | Cod sursa (job #2470501)
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lsb(x) (x & (-x))
using namespace std;
struct Aho {
struct Node {
Node *son[26], *fail;
int cnt;
vector <int> ids;
Node() {
memset(son, NULL, sizeof(son));
fail = NULL, cnt = 0;
}
};
Node *root = new Node;
vector <Node*> Q;
void add(Node *nod, string &str, int pos, int id) {
if(pos == str.size()) {
nod -> ids.push_back(id);
return ;
}
char ch = str[pos] - 'a';
if(nod -> son[ch] == NULL) {
nod -> son[ch] = new Node;
}
add(nod -> son[ch], str, pos + 1, id);
}
inline void addWord(string &str, int id) {
add(root, str, 0, id);
}
inline void bfs() {
int p = 0;
root -> fail = root;
Q.push_back(root);
while(p < Q.size()) {
Node *nod = Q[p++];
for(char ch = 0; ch < 26; ch++) {
if(nod -> son[ch] == NULL) continue;
Node *aux = nod -> fail;
while(aux != root && aux -> son[ch] == NULL) {
aux = aux -> fail;
}
if(aux -> son[ch] == NULL || aux == nod) {
nod -> son[ch] -> fail = aux;
}
else {
nod -> son[ch] -> fail = aux -> son[ch];
}
Q.push_back(nod -> son[ch]);
}
}
}
inline void solve(string &str) {
Node *nod = root;
for(auto &ch : str) {
ch -= 'a';
while(nod != root && nod -> son[ch] == NULL) {
nod = nod -> fail;
}
if(nod -> son[ch] != NULL) nod = nod -> son[ch];
nod -> cnt++;
}
}
inline void antibfs(vector <int> &sol) {
for(int i = Q.size() - 1; i >= 0; i--) {
Node *nod = Q[i];
for(auto it : nod -> ids) {
sol[it] = nod -> cnt;
}
nod -> fail -> cnt += nod -> cnt;
}
}
};
int main() {
#if 1
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
#endif
int i, n;
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
string str;
cin >> str >> n;
Aho aho;
for(i = 0; i < n; i++) {
string word;
cin >> word;
aho.addWord(word, i);
}
vector <int> sol(n);
aho.bfs();
aho.solve(str);
//cerr << "!!\n";
aho.antibfs(sol);
for(i = 0; i < n; i++) {
cout << sol[i] << "\n";
}
return 0;
}