Pagini recente » Cod sursa (job #362476) | Cod sursa (job #1030745) | Cod sursa (job #1064879) | Cod sursa (job #1849044) | Cod sursa (job #1982279)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 7e5 + 10;
int N;
char text[NMAX];
map<char, int> suffixEdge[2 * NMAX];
int suffixLink[2 * NMAX], suffixLength[2 * NMAX];
int DP[2 * NMAX];
bitset<2 * NMAX> vis;
void DFS(int node) {
vis[node] = 1;
for (auto nextNode: suffixEdge[node]) {
if (!vis[nextNode.second])
DFS(nextNode.second);
DP[node] += DP[nextNode.second];
}
}
int main() {
assert(freopen("ahocorasick.in", "r", stdin));
assert(freopen("ahocorasick.out", "w", stdout));
int i;
cin >> text;
int currNode = 0, lastNode = 0, cntNode = 1;
suffixLink[0] = -1;
suffixLength[0] = 0;
for (i = 0; text[i]; ++i) {
currNode = cntNode++;
suffixEdge[lastNode][text[i]] = currNode;
suffixLength[currNode] = suffixLength[lastNode] + 1;
int currSuffix = suffixLink[lastNode];
while (currSuffix != -1 && !suffixEdge[currSuffix].count(text[i])) {
suffixEdge[currSuffix][text[i]] = currNode;
currSuffix = suffixLink[currSuffix];
}
if (currSuffix != -1) {
int nextSuffix = suffixEdge[currSuffix][text[i]];
if (suffixLength[nextSuffix] == suffixLength[currSuffix] + 1) {
suffixLink[currNode] = nextSuffix;
} else {
int newNode = cntNode++;
suffixLength[newNode] = suffixLength[currSuffix] + 1;
suffixEdge[newNode] = suffixEdge[nextSuffix];
suffixLink[newNode] = suffixLink[nextSuffix];
suffixLink[nextSuffix] = suffixLink[currNode] = newNode;
while (currSuffix != -1 && suffixEdge[currSuffix][text[i]] == nextSuffix) {
suffixEdge[currSuffix][text[i]] = newNode;
currSuffix = suffixLink[currSuffix];
}
}
} else
suffixLink[currNode] = 0;
lastNode = currNode;
}
currNode = lastNode;
while (currNode != -1) {
DP[currNode] = 1;
currNode = suffixLink[currNode];
}
DFS(0);
cin >> N;
while (N--) {
cin >> text;
currNode = 0;
for (i = 0; text[i]; ++i) {
if (!suffixEdge[currNode].count(text[i])) {
cout << "0\n";
goto Continue;
}
currNode = suffixEdge[currNode][text[i]];
}
cout << DP[currNode] << '\n';
Continue:;
}
return 0;
}