Cod sursa(job #1504497)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 17 octombrie 2015 20:21:27
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>
#define Nmax 1000005
#define pb push_back

using namespace std;

int n,l;
char a[Nmax],b[Nmax];
vector <int> L[Nmax];

struct Trie
{
    int val;
    bool seen;
    Trie *leg[26],*suf;
    vector <Trie *> inv;
    Trie()
    {
        val=0; seen=0; inv.resize(0);
        for(int i=0;i<26;++i) leg[i]=0;
    }
} *wh[Nmax],*R = new Trie();
queue <Trie*> Q;

inline void Add(Trie *T, int p, int ind)
{
    if(p==l+1)
    {
        wh[ind]=T; return;
    }
    if(T->leg[b[p]-'a']==0) T->leg[b[p]-'a']=new Trie();
    Add(T->leg[b[p]-'a'],p+1,ind);
}

inline void Get_Suf()
{
    Q.push(R);
    while(!Q.empty())
    {
        Trie *T=Q.front(); Q.pop();
        for(int i=0;i<26;++i)
            if(T->leg[i])
            {
                if(T==R) T->leg[i]->suf=R;
                else
                {
                    Trie *cT=T; T=T->suf;
                    while(T!=R && T->leg[i]==0) T=T->suf;
                    if(T->leg[i]) cT->leg[i]->suf=T->leg[i];
                    else cT->leg[i]->suf=R;
                    T=cT;
                }
                Q.push(T->leg[i]);
                T->leg[i]->suf->inv.pb(T->leg[i]);
            }
    }
}

inline void Dfs(Trie *T)
{
    if(!T || T->seen) return;
    T->seen=true;
    for(auto it : T->inv)
    {
        Dfs(it); T->val+=it->val;
    }
}

inline void Solve(Trie *T)
{
    Dfs(T);
    for(int i=0;i<26;++i)
        if(T->leg[i])
            Solve(T->leg[i]);
}

int main()
{
    int m,i;
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");
    cin>>(a+1)>>m;
    n=strlen(a+1);
    for(i=1;i<=m;++i)
    {
        cin>>(b+1); l=strlen(b+1);
        Add(R,1,i);
    }
    Get_Suf();
    Trie *T=R;
    for(i=1;i<=n;++i)
    {
        while(T!=R && T->leg[a[i]-'a']==0) T=T->suf;
        if(T->leg[a[i]-'a']) T=T->leg[a[i]-'a'];
        else T=R;
        T->val++;
    }
    Solve(R);
    for(i=1;i<=m;++i) cout<<wh[i]->val<<"\n";
    return 0;
}