Cod sursa(job #1970712)

Utilizator george_stelianChichirim George george_stelian Data 19 aprilie 2017 15:49:50
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <bits/stdc++.h>

using namespace std;

const int nil=-1,sigma=26;
struct node
{
    int pi,sum;
    vector<int> delta,words;
    node()
    {
        sum=0;
        pi=nil;
        delta.resize(sigma,nil);
    }
};
vector<node> v;
vector<int> q;
int rad,nr_words;
char sir[1000010],sir1[10010];

void add_word(char sir[])
{
    int nod=rad,n=strlen(sir);
    for(int i=0;i<n;i++)
    {
        if(v[nod].delta[sir[i]-'a']==nil)
        {
            v.push_back(node());
            v[nod].delta[sir[i]-'a']=v.size()-1;
        }
        nod=v[nod].delta[sir[i]-'a'];
    }
    v[nod].words.push_back(nr_words++);
}

void compute_pi_delta()
{
    v[rad].pi=rad;
    q.push_back(rad);
    for(int i=0;i<q.size();i++)
    {
        int nod=q[i];
        for(int j=0;j<sigma;j++)
        {
            int k=v[nod].pi;
            while(k!=rad && v[k].delta[j]==nil) k=v[k].pi;
            if(k!=nod && v[k].delta[j]!=nil) k=v[k].delta[j];
            if(v[nod].delta[j]!=nil)
            {
                v[v[nod].delta[j]].pi=k;
                q.push_back(v[nod].delta[j]);
            }
            else v[nod].delta[j]=k;
        }
    }
}

vector<int> get_freq(char sir[])
{
    vector<int> freq=vector<int>(nr_words,0);
    int n=strlen(sir),nod=rad;
    for(int i=0;i<n;i++)
    {
        nod=v[nod].delta[sir[i]-'a'];
        v[nod].sum++;
    }
    for(int i=q.size()-1;i>=1;i--)
        v[v[q[i]].pi].sum+=v[q[i]].sum;
    for(int i=0;i<v.size();i++)
        for(vector<int>::iterator it=v[i].words.begin();it!=v[i].words.end();it++)
            freq[*it]+=v[i].sum;
    return freq;
}

int main()
{
    freopen("ahocorasick.in", "r" ,stdin);
    freopen("ahocorasick.out", "w", stdout);
    int n;
    scanf("%s%d",sir,&n);
    v.push_back(node());
    rad=0;
    for(int i=1;i<=n;i++)
    {
        scanf("\n%s",sir1);
        add_word(sir1);
    }
    compute_pi_delta();
    vector<int> sol=get_freq(sir);
    for(int i=0;i<n;i++) printf("%d\n",sol[i]);
    return 0;
}