Cod sursa(job #2314053)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 7 ianuarie 2019 20:08:50
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include<bits/stdc++.h>
using namespace std;
struct trie
{
    vector<int> words;
    trie *next[27],*error;
    int cnt;
    trie()
    {
        cnt=0;
        words.clear();
        error=0;
        memset(next,0,sizeof(next));
    }
};
trie *root=new trie();
int n,sol[105];
bool not_a;
string a,s;
vector<trie*> ord;
void insert(string w, int idx)
{
    trie *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 trie();
        aux = aux->next[w[i]-'a'];
    }
    aux->words.push_back(idx);
}
void drumuri()
{
    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]);
                trie *start = ord[i]->error;
                while (start!=root && start->next[j]==0) start = start->error;
                if (ord[i]!=root && start->next[j]!=0) ord[i]->next[j]->error = start->next[j];
                else ord[i]->next[j]->error = root;
            }
}
void calc(trie *aux)
{
    for (int i=ord.size()-1; i>=0; --i)
    {
        aux = ord[i];
        aux->error->cnt += aux->cnt;
        for (int j=0; j<aux->words.size(); ++j)
            sol[aux->words[j]]=aux->cnt;
    }
}
int main()
{
    ifstream f("ahocorasick.in");
    ofstream g("ahocorasick.out");
    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;
         if(s[0]!='a')
            not_a = 1;
         insert(s,i);
    }
    root->error=root,drumuri();
    trie *aux=root;
    int lnga=a.length();
    for(int i=0;i<lnga;++i)
    {
        while(!aux->next[a[i]-'a']&&aux!=root)
            aux=aux->error;
        if(aux->next[a[i]-'a'])
            aux=aux->next[a[i]-'a'];
        ++aux->cnt;
    }
    calc(root);
    for(int i=1; i<=n; ++i)
        g<<sol[i]<<"\n";
}