Pagini recente » Cod sursa (job #2595095) | Cod sursa (job #1704858) | Cod sursa (job #1518938) | Cod sursa (job #2857117) | Cod sursa (job #1409935)
#include <iostream>
#include <fstream>
#include <vector>
#include <string.h>
using namespace std;
const int maxn = 1000005;
const int maxlg = 10005;
const int sigma = 26;
char a[maxn], word[maxlg];
int n, ans[maxn];
struct trie {
trie *sons[sigma];
trie *fail;
int cnt;
vector <int> matches;
trie () {
memset(sons, 0, sizeof(sons));
cnt = 0;
matches.clear();
}
} *root = new trie();
vector < trie * > q;
inline void insert(trie *node, char *s, int ind) {
if(!*s) {
node->matches.push_back(ind);
return ;
}
int son = *s - 'a';
if(!node->sons[son])
node->sons[son] = new trie();
insert(node->sons[son], s + 1, ind);
}
inline void buildfail() {
trie * node = root, *k;
node->fail = node;
q.push_back(node);
for(int i = 0 ; i < q.size() ; ++ i) {
node = q[i];
for(int son = 0 ; son < sigma ; ++ son)
if(node->sons[son]) {
k = node->fail;
while(k != root && !k->sons[son])
k = k->fail;
if(node != root && k->sons[son])
k = k->sons[son];
node->sons[son]->fail = k;
q.push_back(node->sons[son]);
}
}
}
inline void aho() { /// ahoi marinari
trie *k = root;
for(int i = 1 ; a[i] ; ++ i) {
int son = a[i] - 'a';
while(k != root && !k->sons[son])
k = k->fail;
if(k->sons[son])
k = k->sons[son];
++ k->cnt;
}
}
inline void revbfs() {
trie *node;
for(int i = q.size() - 1 ; i >= 0 ; -- i) {
node = q[i];
node->fail->cnt += node->cnt;
for(int j = 0 ; j < node->matches.size() ; ++ j)
ans[node->matches[j]] = node->cnt;
}
}
int main() {
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
fin.getline(a + 1, maxn);
fin >> n;
fin.get();
for(int i = 1 ; i <= n ; ++ i) {
fin.getline(word, maxlg);
insert(root, word, i);
}
buildfail();
aho();
revbfs();
for(int i = 1 ; i <= n ; ++ i)
fout << ans[i] << '\n';
}