Pagini recente » Cod sursa (job #1850270) | Cod sursa (job #2465561) | Cod sursa (job #583473) | Cod sursa (job #2776416) | Cod sursa (job #3223128)
#include <bits/stdc++.h>
std::ifstream cin("ahocorasick.in");
std::ofstream cout("ahocorasick.out");
int ans[110],n,v[1000010][30],pd[1000010],nr;
char a[1000010],s[10010];
void adauga(int poz)
{
int spoz=0,nod=0;
while(s[spoz]&&v[nod][s[spoz]-'a'])
{
nod=v[nod][s[spoz]-'a'];
++spoz;
}
while(s[spoz])
{
v[nod][s[spoz]-'a']=++nr;
nod=nr;
++spoz;
}
v[nod][26]=poz;
}
void construiestesufix()
{
std::queue<int>q;
for(int i=0;i<26;++i)
if(v[0][i])
q.push(v[0][i]);
while(!q.empty())
{
int nod=q.front();
q.pop();
for(int i=0;i<26;++i)
if(v[nod][i])
{
int nodant=v[nod][27];
while(nodant!=0&&v[nodant][i]==0)
nodant=v[nodant][27];
if(v[nodant][i])
v[v[nod][i]][27]=v[nodant][i];
q.push(v[nod][i]);
}
}
}
int calculeaza(int nod)
{
int ansac=pd[nod];
for(int i=0;i<26;++i)
{
if(v[nod][i])
ansac+=calculeaza(v[nod][i]);
}
ans[v[nod][26]]=ansac;
return ansac;
}
bool eliminadin(int nod,int deac,int demax)
{
if(deac==demax)
{
ans[v[nod][26]]=pd[nod];
v[nod][26]=-1;
pd[nod]=0;
return false;
}
bool ok=false;
if(v[nod][26])
ok=true;
for(int i=0;i<26;++i)
if(v[nod][i])
{
if(eliminadin(v[nod][i],deac+1,demax)==false)
v[nod][i]=0;
else
ok=true;
}
pd[nod]=0;
return ok;
}
int sufix(int nod)
{
if(v[nod][26]!=-1)return nod;
return v[nod][27]=sufix(v[nod][27]);
}
void schimbasufix(int nod)
{
for(int i=0;i<26;++i)
if(v[nod][i])
schimbasufix(v[nod][i]);
v[nod][27]=sufix(v[nod][27]);
}
int aflaadancimemaxima(int nod)
{
int ans=0;
for(int i=0;i<26;++i)
if(v[nod][i])
ans=std::max(ans,aflaadancimemaxima(v[nod][i]));
return ans+1;
}
void elimina()
{
eliminadin(0,1,aflaadancimemaxima(0));
if(v[0][26]!=-1)
schimbasufix(0);
}
void parcurge()
{
int nod=0;
for(int i=0;a[i];++i)
{
while(nod!=0&&v[nod][a[i]-'a']==0)
{
++pd[nod];
nod=v[nod][27];
}
nod=v[nod][a[i]-'a'];
}
++pd[nod];
elimina();
}
int main()
{
cin>>a;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>s;
adauga(i);
}
construiestesufix();
while(v[0][26]!=-1)
parcurge();
calculeaza(0);
for(int i=1;i<=n;++i)
cout<<ans[i]<<'\n';
return 0;
}