Cod sursa(job #2442904)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 25 iulie 2019 18:58:45
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#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; vector <int> List;
    Trie * Son[28], * Match;

    Trie()
    {
        val = 0; Match = NULL;

        for(int i = 0; i < 28; i++)
            Son[i] = NULL;
    }
};
Trie * Root = new Trie;

vector <Trie*> V;

void Add(Trie * & Nod, 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;

    Add(Nod -> Son[c], T + 1, i);
}

void BFS()
{
    V.push_back(Root);
    Root -> Match = Root;

    for(int i = 0; i < V.size(); i++)
    {
        Trie * Tata = V[i];

        for(int c = 0; c < 28; c++)
        {
            Trie * Nod = Tata -> Son[c];
            if(!Nod) continue;

            Trie * Finder = 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];

            if(Nod -> Match == Nod)
                Nod -> Match = Root;

            V.push_back(Nod);
        }
    }
}

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()
{
    while(!V.empty())
    {
        Trie * Nod = V.back(); V.pop_back();

        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, W, i);

    BFS(); Solve(); Spread();

    for(int i = 1; i <= N; i++)
        fout << Sol[i] << '\n';

    fin.close();
    fout.close();

    return 0;
}