Pagini recente » Cod sursa (job #2575451) | Cod sursa (job #2948268) | Cod sursa (job #2566717) | Cod sursa (job #2406707) | Cod sursa (job #2231744)
#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;
cin >> n;
ans.resize (n + 1);
root = new Node ();
root -> suffLink = root;
for (int i = 1; i <= n; ++ i) {
string aux;
cin >> aux;
m_Insert (aux, i);
}
m_SetLinks ();
}
void Solve () {
Node* curNode = root;
for (auto x : s) {
if (not curNode -> nextNode[L (x)]) {
while (curNode != root) {
if (curNode -> nextNode[L (x)]) {
break;
}
curNode = curNode -> suffLink;
}
}
if (curNode -> nextNode[L (x)]) {
curNode = curNode -> nextNode[L (x)];
}
++ curNode -> frecv;
/* cerr << "lol\n"; */
}
/* cerr << "alle"; */
m_Complete (root);
for (int i = 1; i <= n; ++ i) {
cout << ans[i] << '\n';
}
}
private:
struct Node {
Node () {
frecv = 0;
wordIndex = 0;
suffLink = nullptr;;
for (int i = 0; i < 26; ++ i) {
nextNode[i] = nullptr;
}
}
int frecv, wordIndex;
Node *nextNode[26], *suffLink;
vector < Node* > inv;
};
int n;
string s;
Node *root;
vector < int > ans;
void m_Insert (string &s, int wordIndex) {
Node *curNode = root;
for (auto x : s) {
if (not curNode -> nextNode[L (x)]) {
curNode -> nextNode[L (x)] = new Node ();
}
curNode = curNode -> nextNode[L (x)];
}
curNode -> wordIndex = wordIndex;
}
void m_SetLinks () {
queue < Node* > q;
for (int i = 0; i < 26; ++ i) {
if (root -> nextNode[i]) {
q.push (root -> nextNode[i]);
root -> nextNode[i] -> suffLink = root;
root -> inv.push_back (root -> nextNode[i]);
}
}
while (not q.empty ()) {
auto curNode = q.front ();
q.pop ();
for (int i = 0; i < 26; ++ i) {
if (not curNode -> nextNode[i]) {
continue;
}
auto me = curNode -> suffLink;
while (me != root) {
if (me -> nextNode[i]) {
break;
}
me = me -> suffLink;
}
if (me -> nextNode[i]) {
curNode -> nextNode[i] -> suffLink = me -> nextNode[i];
me -> nextNode[i] -> inv.push_back (curNode -> nextNode[i]);
}
else {
curNode -> nextNode[i] -> suffLink = root;
root -> inv.push_back (curNode -> nextNode[i]);
}
q.push (curNode -> nextNode[i]);
}
}
}
void m_Complete (Node *curNode) {
for (auto x : curNode -> inv) {
m_Complete (x);
curNode -> frecv += x -> frecv;
}
ans[curNode -> wordIndex] = curNode -> frecv;
}
};
int main () {
ios::sync_with_stdio (false);
cin.tie (0);cout.tie (0);
/* freopen ("ahocorasick.in", "r", stdin); */
/* freopen ("ahocorasick.out", "w", stdout); */
Aho aho;
aho.Solve ();
}