Pagini recente » Cod sursa (job #285059) | Cod sursa (job #2646568) | Cod sursa (job #2235869) | Cod sursa (job #3304076)
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
static const int MAXS = 1000000 + 5;
static const int ALPHA = 26;
int nxt[MAXS][ALPHA], fail[MAXS];
int node_cnt = 1; // 0 = root
int endNode[105]; // starea în care se termină pattern-ul i
long long cntState[MAXS];
int main(){
// I/O din fișiere și STDIO rapid
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
static char A[1000005];
int n;
// Citim textul și numărul de pattern‑uri
scanf("%s", A);
scanf("%d", &n);
// Construim trie‑ul și reținem endNode pentru fiecare pattern
for(int id = 1; id <= n; id++){
static char s[10005];
scanf("%s", s);
int u = 0;
for(int i = 0; s[i]; i++){
int c = s[i] - 'a';
if(!nxt[u][c]) nxt[u][c] = node_cnt++;
u = nxt[u][c];
}
endNode[id] = u;
}
// BFS pentru fail & completare tranziții, păstrăm ordinea în bfsOrd
vector<int> bfsOrd;
queue<int> q;
// nivel 1
for(int c = 0; c < ALPHA; c++){
int v = nxt[0][c];
if(v){
fail[v] = 0;
q.push(v);
bfsOrd.push_back(v);
}
}
while(!q.empty()){
int u = q.front(); q.pop();
for(int c = 0; c < ALPHA; c++){
int v = nxt[u][c];
if(v){
int f = fail[u];
while(f && !nxt[f][c]) f = fail[f];
fail[v] = nxt[f][c];
q.push(v);
bfsOrd.push_back(v);
} else {
nxt[u][c] = nxt[ fail[u] ][c];
}
}
}
// Parcurgem textul și înregistrăm vizitele în cntState
int cur = 0;
for(int i = 0; A[i]; i++){
int c = A[i] - 'a';
cur = nxt[cur][c];
cntState[cur]++;
}
// Propagăm înapoi pe fail, în ordinea inversă BFS
for(int i = (int)bfsOrd.size()-1; i >= 0; --i){
int u = bfsOrd[i];
cntState[ fail[u] ] += cntState[u];
}
// Pentru fiecare pattern, răspunsul e cntState[endNode[id]]
for(int id = 1; id <= n; id++){
printf("%lld\n", cntState[ endNode[id] ]);
}
return 0;
}