Pagini recente » Cod sursa (job #262095) | Cod sursa (job #1045900) | Cod sursa (job #262103) | Cod sursa (job #411089) | Cod sursa (job #2442880)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
const int LMax = 10002;
char S[1000005], W[LMax + 5];
int N, Sol[105];
struct Trie
{
int val; char l; vector <int> List;
Trie * Son[28], * Match, * Tata;
Trie()
{
val = 0; Match = Tata = NULL; l = 0;
for(int i = 0; i < 28; i++)
Son[i] = NULL;
}
};
Trie * Root = new Trie;
vector <Trie*> V[LMax + 5];
void Add(Trie * & Nod, int lev, char * T, int i)
{
if(*T == 0)
{
Nod -> List.push_back(i);
return;
}
char c = *T - 'a';
if(Nod -> Son[c] == NULL)
{
Nod -> Son[c] = new Trie;
V[lev + 1].push_back(Nod -> Son[c]);
Nod -> Son[c] -> Tata = Nod;
Nod -> Son[c] -> l = *T;
}
Add(Nod -> Son[c], lev + 1, T + 1, i);
}
void BFS()
{
for(int i = 2; i <= LMax; i++)
for(auto Nod : V[i])
{
char c = Nod -> l - 'a';
Trie * Finder = Nod -> Tata -> Match;
while(Finder -> Son[c] == NULL && Finder != Root)
Finder = Finder -> Match;
if(Finder -> Son[c] == NULL)
Nod -> Match = Root;
else
Nod -> Match = Finder -> Son[c];
}
}
void Solve()
{
Trie * Nod = Root;
for(int i = 0; S[i]; i++)
{
char c = S[i] - 'a';
while(Nod -> Son[c] == NULL && Nod != Root)
Nod = Nod -> Match;
if(Nod -> Son[c])
{
Nod = Nod -> Son[c];
Nod -> val++;
}
}
}
void Spread()
{
for(int i = LMax; i > 0; i--)
for(auto Nod : V[i])
{
for(auto j : Nod -> List)
Sol[j] = Nod -> val;
Nod -> Match -> val += Nod -> val;
}
}
int main()
{
fin >> S >> N;
for(int i = 1; i <= N; i++)
fin >> W, Add(Root, 0, W, i);
Root -> Match = Root -> Tata = Root;
for(int i = 0; i < 28; i++)
{
if(Root -> Son[i] != NULL)
Root -> Son[i] -> Match = Root;
}
BFS(); Solve(); Spread();
for(int i = 1; i <= N; i++)
fout << Sol[i] << '\n';
fin.close();
fout.close();
return 0;
}