Pagini recente » Cod sursa (job #18525) | Cod sursa (job #2864715) | Cod sursa (job #1986166) | Cod sursa (job #3222350) | Cod sursa (job #2231718)
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#define L(x) x - 'a'
using namespace std;
const int MAX = 1e6 + 7;
ifstream cin ("ahocorasick.in");
ofstream cout ("ahocorasick.out");
class Aho {
public:
Aho () {
cin >> s;
memIndex = 0;
gr.resize (MAX);
lvl.resize (MAX);
tree.resize (MAX);
cin >> n;
ans.resize (n + 1);
for (int i = 1; i <= n; ++ i) {
string aux;
cin >> aux;
m_Insert (aux, i);
}
m_SetLinks ();
}
void Solve () {
int curNode = 0;
for (auto x : s) {
if (not tree[curNode].letter[L (x)]) {
while (curNode) {
if (tree[curNode].letter[L (x)]) {
break;
}
curNode = tree[curNode].suffLink;
}
}
curNode = tree[curNode].letter[L (x)];
++ tree[curNode].frecv;
}
queue < int > q;
for (int i = 1; i <= memIndex; ++ i) {
if (not lvl[i]) {
q.push (i);
}
}
while (not q.empty ()) {
curNode = q.front ();
q.pop ();
tree[tree[curNode].suffLink].frecv += tree[curNode].frecv;
for (auto x : gr[curNode]) {
if (--lvl[x] == 0) {
q.push (x);
}
}
}
for (int i = 1; i <= memIndex; ++ i) {
ans[tree[i].wordIndex] = tree[i].frecv;
}
for (int i = 1; i <= n; ++ i) {
cout << ans[i] << '\n';
}
}
private:
struct Node {
Node () {
frecv = 0;
suffLink = 0;
wordIndex = 0;
for (int i = 0; i < 26; ++ i) {
letter[i] = 0;
}
}
int frecv, suffLink, wordIndex, letter[26];
};
string s;
int n, memIndex;
vector < Node > tree;
vector < int > ans, lvl;
vector < vector < int > > gr;
void m_Insert (string &s, int wordIndex) {
int curNode = 0;
for (auto x : s) {
if (not tree[curNode].letter[L (x)]) {
tree[curNode].letter[L (x)] = ++ memIndex;
++ lvl[curNode];
gr[memIndex].push_back (curNode);
}
curNode = tree[curNode].letter[L (x)];
}
tree[curNode].wordIndex = wordIndex;
}
void m_SetLinks () {
queue < int > q;
for (int i = 0; i < 26; ++ i) {
if (tree[0].letter[i]) {
q.push (tree[0].letter[i]);
}
}
while (not q.empty ()) {
int cur = q.front ();
q.pop ();
for (int i = 0; i < 26; ++ i) {
if (not tree[cur].letter[i]) {
continue;
}
int me = tree[cur].suffLink;
while (me) {
if (tree[me].letter[i]) {
break;
}
me = tree[me].suffLink;
}
++ lvl[tree[me].letter[i]];
gr[tree[cur].letter[i]].push_back (tree[me].letter[i]);
tree[tree[cur].letter[i]].suffLink = tree[me].letter[i];
q.push (tree[cur].letter[i]);
}
}
}
};
int main () {
ios::sync_with_stdio (false);
cin.tie (0);cout.tie (0);
Aho aho;
aho.Solve ();
}