Cod sursa(job #1520937)

Utilizator ArchazeyBaltatu Andrei-Mircea Archazey Data 9 noiembrie 2015 18:54:31
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include<bits/stdc++.h>
using namespace std;

struct Trie
{
    int val;
    bool viz;
    Trie *leg,*t[26];
    vector<Trie*>inv;
    Trie()
    {
        val=viz=0;
        for (int i=0;i<26;i++) t[i]=NULL;
    }
};

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

const int NMAX=1000005;
const int XMAX=10005;

int n,m,len;
char a[NMAX],b[XMAX];
Trie *root=new Trie(),*word[XMAX];
queue<Trie*>Q;

void Add(Trie *p,int poz,int ind)
{
    if (poz==len+1)
    {
        word[ind]=p;
        return ;
    }
    if (p->t[b[poz]-'a']==NULL) p->t[b[poz]-'a']=new Trie();
    Add(p->t[b[poz]-'a'],poz+1,ind);
}

void Bfs()
{
    int i;
    Trie *p,*kkt;
    Q.push(root);
    while (!Q.empty())
    {
        p=Q.front();Q.pop();
        for (i=0;i<26;i++)
            if (p->t[i]!=NULL)
            {
                if (p==root)//sigur leg va fi root
                    p->t[i]->leg=root;
                else
                {
                    kkt=p;p=p->leg;
                    while (p!=root && p->t[i]==NULL) p=p->leg;
                    if (p->t[i]!=NULL) p=p->t[i];
                    kkt->t[i]->leg=p;
                    p=kkt;
                }
                Q.push(p->t[i]);
                p->t[i]->leg->inv.push_back(p->t[i]);
            }
    }
}

void Dfs(Trie *p)
{
    if (p->viz==1) return ;
    p->viz=1;
    for (vector<Trie*>::iterator it=p->inv.begin();it!=p->inv.end();it++)
    {
        Dfs(*it);
        p->val+=(*it)->val;
    }
}

void Solve(Trie *p)
{
    Dfs(p);
    for (int i=0;i<25;i++)
        if (p->t[i]!=NULL)
            Solve(p->t[i]);
}

int main()
{
    int i;
    Trie *p;
    fin>>(a+1);
    n=strlen(a+1);
    fin>>m;
    for (i=1;i<=m;i++)
    {
        fin>>(b+1);
        len=strlen(b+1);
        Add(root,1,i);
    }
    Bfs();

    p=root;
    for (i=1;i<=n;i++)
    {
        while (p!=root && p->t[a[i]-'a']==NULL) p=p->leg;
        if (p->t[a[i]-'a']!=NULL) p=p->t[a[i]-'a'];
        p->val++;
    }

    Solve(root);
    for (i=1;i<=m;i++) fout<<word[i]->val<<"\n";
    return 0;
}