Cod sursa(job #2270796)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 27 octombrie 2018 16:09:26
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 kb
#include <fstream>
#include <vector>
#include <cstring>
#define NM 100010
 
using namespace std;
 
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
 
struct Trie
{
    Trie *Fail;
    int nr;
    Trie *Sons[26];
    vector<int> out;
 
    Trie ()
    {
        Fail=0;
        nr=0;
        memset(Sons,0,sizeof(Sons));
    }
} *T=new Trie();
 
int N,i;
string S,STR;
int ANS[NM];
int P,U;
 
void Insert (Trie *T, char *p, int i)
{
    if ('a'>*p || *p>'z')
    {
        T->out.push_back(i);
        return;
    }
 
    int next=*p-'a';
    if (T->Sons[next])
        Insert(T->Sons[next],++p,i);
    else
    {
        T->Sons[next]=new Trie();
        Insert(T->Sons[next],++p,i);
    }
}
 
Trie *Q[NM];
Trie *CT,*R;
 
int main ()
{
    getline(f,STR);
    f >> N;
    getline(f,S);
 
    for (i=1; i<=N; i++)
    {
        getline(f,S);
        Insert(T,&S[0],i);
    }
 
    Q[P=U=1]=T;
    T->Fail=T;
 
    while (P<=U)
    {
        CT=Q[P++];
        for (i=0; i<26; i++)
            if (CT->Sons[i])
            {
                for (R=CT->Fail; R!=T && R->Sons[i]==0; R=R->Fail);
                if (R->Sons[i] && R->Sons[i]!=CT->Sons[i])
                    R=R->Sons[i];
                CT->Sons[i]->Fail=R;
                Q[++U]=CT->Sons[i];
            }
    }
 
    T->Fail=0;
 
    CT=T;
    for (i=0; i<STR.size(); i++)
    {
        int next=STR[i]-'a';
        for (;CT->Sons[next]==0 && CT!=T; CT=CT->Fail);
        if (CT->Sons[next]) CT=CT->Sons[next];
        ++CT->nr;
    }
 
    for (i=U; i>=1; i--)
    {
        CT=Q[i];
        if (CT->Fail) CT->Fail->nr+=CT->nr;
 
        for (int j=0; j<CT->out.size(); j++)
                ANS[CT->out[j]]=CT->nr;
    }
 
    for (i=1; i<=N; i++)
        g << ANS[i] << '\n';
 
    f.close();
    g.close();
    return 0;
}