Pagini recente » Cod sursa (job #337726) | Cod sursa (job #2491846) | Cod sursa (job #2230117) | Cod sursa (job #711063) | Cod sursa (job #2853343)
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string s;
int n;
int sol[105];
struct nod
{
int lit=0;
vector<int> isfin;
int niv,cnt,par;
int kid[31];
int suflink=-1;
int tran[31];
};
nod emp;
vector<nod> trie;
int getsuflink(int nod);
int gettran(int nod,int lit);
void addstring(string t,int ind)
{
int poz=0;
for(int i=0;i<t.size();i++)
{
int lit=t[i]-'a'+1;
if(trie[poz].kid[lit]==-1)
{
nod x=emp;
x.lit=lit;
x.niv=trie[poz].niv+1;
trie.push_back(x);
int index=trie.size()-1;
trie[poz].kid[lit]=index;
trie[index].par=poz;
}
poz=trie[poz].kid[lit];
if(i+1==t.size())
trie[poz].isfin.push_back(ind);
}
}
int getsuflink(int nod)
{
if(trie[nod].suflink!=-1)
return trie[nod].suflink;
if(nod==0||trie[nod].par==0)
{
trie[nod].suflink=0;
return 0;
}
int lit=trie[nod].lit;
int par=trie[nod].par;
trie[nod].suflink=gettran(getsuflink(par),lit);
return trie[nod].suflink;
}
int gettran(int nod, int lit)
{
if(trie[nod].tran[lit]!=-1)
return trie[nod].tran[lit];
if(trie[nod].kid[lit]!=-1)
{
trie[nod].tran[lit]=trie[nod].kid[lit];
return trie[nod].tran[lit];
}
if(nod==0)
{
trie[nod].tran[lit]=0;
return 0;
}
trie[nod].tran[lit]=gettran(getsuflink(nod),lit);
return trie[nod].tran[lit];
}
bool comp(int a,int b)
{
return trie[a].niv>trie[b].niv;
}
int main()
{
fin>>s;
fin>>n;
for(int i=1;i<=26;i++)
emp.kid[i]=emp.tran[i]=-1;
trie.push_back(emp);
for(int i=1;i<=n;i++)
{
string t;
fin>>t;
addstring(t,i);
}
for(int i=0;i<trie.size();i++)
{
getsuflink(i);
for(int lit=1;lit<=26;lit++)
gettran(i,lit);
}
int nod=0;
for(int i=0;i<s.size();i++)
{
int lit=s[i]-'a'+1;
nod=gettran(nod,lit);
trie[nod].cnt++;
}
vector<int> vals;
for(int i=0;i<trie.size();i++)
vals.push_back(i);
sort(vals.begin(),vals.end(),comp);
for(int i:vals)
{
for(int j:trie[i].isfin)
sol[j]+=trie[i].cnt;
int nod=trie[i].suflink;
trie[nod].cnt+=trie[i].cnt;
}
for(int i=1;i<=n;i++)
fout<<sol[i]<<'\n';
return 0;
}