Mai intai trebuie sa te autentifici.
Cod sursa(job #1153766)
Utilizator | Data | 25 martie 2014 18:31:48 | |
---|---|---|---|
Problema | Aho-Corasick | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 1.66 kb |
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
struct ac{
vector <int> words;
int n0;
ac *f[26], *fail;
ac()
{
n0=0;
fail=0;
memset(f, 0, sizeof(f));
}
};
ac *Q[100003], *T=new ac;
char a[1000005], word[10005];
int sol[105], Qst, Qdr;
void ac_insert(ac *T, char *s, int i)
{
if(*s=='\n')
{
T->words.push_back(i);
return;
}
if(!T->f[*s-'a']) T->f[*s-'a']=new ac;
ac_insert(T->f[*s-'a'], s+1, i);
}
void ac_bfs(ac *T)
{
ac *p, *k;
int i;
T->fail=T;
for(Q[Qst=Qdr=1]=T;Qst<=Qdr;Qst++)
{
p=Q[Qst];
for(i=0;i<26;i++)
{
if(!p->f[i]) continue;
for(k=p->fail;k!=T&&!k->f[i];k=k->fail);
if(k->f[i]&&k!=p) k=k->f[i];
p->f[i]->fail=k;
Q[++Qdr]=p->f[i];
}
}
T->fail=0;
}
void ac_antibfs(ac *T)
{
int i;
ac *p;
for(i=Qdr;i;i--)
{
p=Q[i];
if(p->fail) p->fail->n0+=p->n0;
for(auto x: p->words) sol[x]=p->n0;
}
}
int main()
{
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
int n, m, i, x;
fgets(a, 1000005, stdin); m=strlen(a)-1;
scanf("%d\n", &n);
for(i=1;i<=n;i++)
{
fgets(word, 10005, stdin);
ac_insert(T, word, i);
}
ac_bfs(T);
ac *p=T;
for(i=0;i<m;i++)
{
x=a[i]-'a';
for(;!p->f[x]&&p!=T;p=p->fail);
if(p->f[x]) p=p->f[x];
p->n0++;
}
ac_antibfs(T);
for(i=1;i<=n;i++) printf("%d\n", sol[i]);
}