Pagini recente » Cod sursa (job #379766) | Cod sursa (job #2485870) | Cod sursa (job #2628298) | Profil duticamdiana | Cod sursa (job #2331843)
#include <bits/stdc++.h>
struct trie_node {
trie_node() {
fail = NULL; count = 0;
for (int i=0; i<30; ++i)
sons[i] = NULL;
} int count;
trie_node *fail, *sons[30];
std::vector <int> endstr;
};
template <typename NodeType>
class AhoCorasick {
public:
AhoCorasick() {Root = new NodeType;}
std::string Str;
void Build() {
BuildQueue.push(Root);
Root->fail = Root;
NodeType *p, *node;
while (!BuildQueue.empty()) {
p = BuildQueue.front();
BuildQueue.pop();
Order.push_back(p);
for (int i=0; i<30; ++i)
if (p->sons[i] != NULL) {
node = p->fail;
while (node != Root && node->sons[i] == NULL && node != node->fail)
node = node->fail;
if (node->sons[i] != NULL && node->sons[i] != p->sons[i])
node = node->sons[i];
p->sons[i]->fail = node;
BuildQueue.push(p->sons[i]);
}
} Root->fail = NULL;
}
void Compute(int Count[]) {
NodeType *p = Root;
for (int i=0, son; i<Str.size(); ++i) {
son = Str[i] - 'a';
while (p->sons[son] == NULL && p != Root && p != p->fail)
p = p->fail;
if (p->sons[son] != NULL)
p = p->sons[son];
p->count ++;
}
for (int i=Order.size()-1; i>=0; --i) {
p = Order[i];
if (p->fail != NULL)
p->fail->count += p->count;
for (auto it:p->endstr)
Count[it] = p->count;
}
}
void insert(const std::string &str, int idx) {
NodeType *ptr = Root;
for (int i=0, son=0; i<str.size(); ++i, ptr = ptr->sons[son]) {
son = str[i] - 'a';
if (ptr->sons[son] == NULL)
ptr->sons[son] = new NodeType;
} ptr->endstr.push_back(idx);
}
private:
NodeType *Root;
std::queue <NodeType*> BuildQueue;
std::vector <NodeType*> Order;
}; AhoCorasick <trie_node> AC;
#define MAXN 105
int N, Count[MAXN];
std::string str[MAXN];
std::ifstream In("ahocorasick.in");
std::ofstream Out("ahocorasick.out");
void Citire() {
In >> AC.Str >> N;
for (int i=0; i<N; ++i)
In >> str[i], AC.insert(str[i], i);
}
void Rezolvare() {
AC.Build();
AC.Compute(Count);
for (int i=0; i<N; ++i, Out << '\n')
Out << Count[i];
}
int main()
{
Citire();
Rezolvare();
return 0;
}