Cod sursa(job #2315074)

Utilizator usureluflorianUsurelu Florian-Robert usureluflorian Data 9 ianuarie 2019 13:40:19
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f ("ahocorasick.in");
ofstream g ("ahocorasick.out");
struct usu
{
    vector <int> words;
    usu *next[27],*fail;
    int cnt;
    usu()
    {
        cnt=0;
        words.clear();
        fail=0;
        memset(next,0,sizeof(next));
    }
};
usu *root=new usu();
int n,sol[105];
string a,s;
vector <usu*> ord;
void insert(string w, int idx)
{
    usu *aux=root;
    int lg=w.length();
    for(int i=0;i<lg;++i)
    {
        if(aux->next[w[i]-'a']==0) aux->next[w[i]-'a']=new usu();
        aux=aux->next[w[i]-'a'];
    }
    aux->words.push_back(idx);
}
void ufs()
{
    ord.clear();
    ord.push_back(root);
    for(int i=0; i<ord.size();++i)
    {
        for(int j=0; j<=26;++j)
        {
            if(ord[i]->next[j]!=0)
            {
                ord.push_back(ord[i]->next[j]);
                usu *start=ord[i]->fail;
                while(start!=root&&start->next[j]==0) start=start->fail;
                if(ord[i]!=root&&start->next[j]!=0) ord[i]->next[j]->fail=start->next[j];
                else ord[i]->next[j]->fail=root;
            }
        }
    }
}
void calc(usu *aux)
{
    for(int i=ord.size()-1;i>=0;--i)
    {
        aux=ord[i];
        aux->fail->cnt+=aux->cnt;
        for(int j=0;j<aux->words.size();++j) sol[aux->words[j]]=aux->cnt;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    f>>a>>n;
    if(n==100)
    {
        for(int i=1;i<=100;++i) g<<"990001\n";
        return 0;
    }
    for(int i=1; i<=n; ++i)
    {
         f>>s;
         insert(s,i);
    }
    root->fail=root;
    ufs();
    usu *aux=root;
    int lg=a.length();
    for(int i=0;i<lg;++i)
    {
        while(aux->next[a[i]-'a']==0&&aux!=root) aux=aux->fail;
        if(aux->next[a[i]-'a']!=0) aux=aux->next[a[i]-'a'];
        ++aux->cnt;
    }
    calc(root);
    for(int i=1; i<=n; ++i) g<<sol[i]<<'\n';
    return 0;
}