Pagini recente » Cod sursa (job #117932) | Cod sursa (job #1254055) | Cod sursa (job #2068769) | Cod sursa (job #3259285) | Cod sursa (job #1519924)
#include<fstream>
#include<iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define pb push_back
using namespace std;
char s[1000100], t[10100];
int N, r1[10100],r[10100];
int Q[10100],st,dr;
vector<int> sol, w[10100];
struct Trie {
int cnt, nrc, ind;
Trie *q[26];
Trie *f;
Trie(int x) {
cnt = nrc = 0;
ind = x;
for(int i=0;i<26;++i) {
q[i] = 0;
}
w[ind].pb(ind);
}
};
Trie *T = new Trie(0);
vector<Trie*> v;
void ins(Trie *nod, char *s) {
if(*s=='\n') {
sol.pb(nod->ind);
++nod->cnt;
return;
}
if(nod->q[*s-'a']==0) {
Trie *nt = new Trie(v.size());
v.pb(nt);
nod->q[*s-'a'] = nt;
++nod->nrc;
}
ins(nod->q[*s-'a'],s+1);
}
void make_fail() {
for(int i=0;i<26;++i) {
if(v[0]->q[i] == 0) continue;
Trie *y = v[0]->q[i];
Q[dr++] = y->ind;
y->f = v[0];
}
while(st < dr) {
int x = Q[st++];
for(int i=0;i<26;++i) {
if(v[x]->q[i] == 0) continue;
Trie *y = v[x]->q[i];
Trie *curr = v[x]->f;
while(curr != 0 && curr->q[i] == 0) {
curr = curr->f;
}
if(curr == 0) {
y->f = v[0];
} else {
y->f = curr->q[i];
}
for(auto j: w[y->f->ind]) {
w[y->ind].pb(j);
}
Q[dr++] = y->ind;
}
}
}
void do_magic() {
int L = strlen(s);
Trie *curr = v[0];
for(int i=0;i<L;++i) {
int c = s[i]-'a';
while(curr != 0 && curr->q[c] == 0) {
curr = curr->f;
}
if(curr == 0) {
curr = v[0];
} else {
++r1[curr->q[c]->ind];
curr = curr->q[c];
}
}
for(int i=1;i<v.size();++i) {
for(int j=0;j<w[i].size();++j) {
r[w[i][j]] += r1[i];
}
}
}
int main() {
//freopen("input.in","r",stdin);
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
scanf("%s%d",s,&N);
v.pb(T);
for(int i=1;i<=N;++i) {
scanf("%s",t);
t[strlen(t)] = '\n';
ins(T,t);
}
make_fail();
do_magic();
for(auto x: sol) {
printf("%d\n",r[x]);
}
return 0;
}