Pagini recente » Cod sursa (job #106275) | Cod sursa (job #587503) | Cod sursa (job #1215905) | Cod sursa (job #501312) | Cod sursa (job #1969374)
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (auto it: (x))
#define pb push_back
#define SZ(x) ((int)(x).size())
int n;
char text[1000005];
char word[105][10005];
struct Trie {
int cnt;
Trie *sons[26],*bck;
vector<Trie*> G;
Trie() {
cnt = 0; bck = 0;
REP(i,26) sons[i] = 0;
G = vector<Trie*>();
}
};
Trie *leaf[105];
Trie *root = new Trie;
void addWord(Trie *T,char *c,int wordID)
{
if (*c == 0) {
leaf[wordID] = T;
return;
}
int nxt = *c - 'a';
if (T->sons[nxt] == 0)
T->sons[nxt] = new Trie;
addWord(T->sons[nxt],c+1,wordID);
}
void buildBackEdges()
{
queue<Trie*> Q;
Q.push(root);
while (!Q.empty()) {
Trie *parent = Q.front(); Q.pop();
REP(i,26) if (parent->sons[i] != 0) {
Trie *b = parent->bck;
while (b != 0 && b->sons[i] == 0) b = b->bck;
if (b == 0)
b = root;
else b = b->sons[i];
parent->sons[i]->bck = b;
b->G.pb(parent->sons[i]);
Q.push(parent->sons[i]);
}
}
}
void dfs(Trie *T)
{
FOREACH(it,T->G) {
dfs(it);
T->cnt += it->cnt;
}
}
int main()
{
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
fin >> text >> n;
FOR(i,1,n) {
fin >> word[i];
addWord(root,word[i],i);
}
buildBackEdges();
Trie *curr = root;
for (char *c = text; *c; c++) {
int nxt = *c - 'a';
while (curr != 0 && curr->sons[nxt] == 0) curr = curr->bck;
if (curr == 0) curr = root;
else curr = curr->sons[nxt];
curr->cnt++;
}
dfs(root);
FOR(i,1,n) fout << leaf[i]->cnt << "\n";
}