Cod sursa(job #2345843)

Utilizator RaduXD1Nicolae Radu RaduXD1 Data 16 februarie 2019 19:00:28
Problema Aho-Corasick Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.09 kb
#include<fstream>
#include<queue>
using namespace std;
ifstream fin ("ahocorasick.in");
ofstream fout("ahocorasick.out");
struct nod{vector<nod*> v;nod *b;nod *tata;int ok;int sol;nod *fiu[26];};
int t,i,h;
char c[101][10001],sir[1000001];
nod *baza,*relu,*sus,*jos;
deque<nod*> q;
void reset(nod *lvl){lvl->b=NULL;lvl->tata=NULL;for(int i=0;i<=25;i++) lvl->fiu[i]=NULL;lvl->sol=0;}
void creaza(int niv, nod *lvl)
{
    if(c[h][niv]==0) return;
    int ca=c[h][niv]-'a';nod *r;
    r=lvl->fiu[ca];
    if(r==NULL)
    {
        r=new nod;
        reset(r);
        lvl->fiu[ca]=r;
        r->tata=lvl;
        r->ok=ca;
    }
    creaza(niv+1, r);
}
void solve(int niv, nod *lvl)
{
    int ca=c[h][niv]-'a';
    lvl=lvl->fiu[ca];
    if(c[h][niv+1]==0) fout<<lvl->sol<<"\n";
    else solve(niv+1, lvl);
}
void dfs(nod *lvl)
{
    for(auto it: lvl->v)
    {
        dfs(it);
        lvl->sol+=it->sol;
    }
}
int main ()
{
    baza=new nod;
    reset(baza);baza->b=baza;
    fin>>sir;fin>>t;
    for(h=1;h<=t;h++)
    {
        fin>>c[h];
        creaza(0, baza);
    }
    q.push_back(baza);
    while(!q.empty())
    {
        relu=q[0];q.pop_front();
        for(i=0;i<=25;i++) if(relu->fiu[i]!=NULL) q.push_back(relu->fiu[i]);
        if(relu!=baza)
        {
            if(relu->tata==baza){relu->b=baza;baza->v.push_back(relu);continue;}
            jos=relu->tata;sus=jos->b;
            while(true)
            {
                if(sus->fiu[relu->ok]!=NULL)
                    {relu->b=sus->fiu[relu->ok];sus->fiu[relu->ok]->v.push_back(relu);break;}
                if(sus==baza){relu->b=baza;baza->v.push_back(relu);break;}
                jos=sus;sus=sus->b;
            }
        }
    }
    int ca;
    relu=baza;
    for(i=0;sir[i]!=0;i++)
    {
        ca=sir[i]-'a';
        while(relu->fiu[ca]==NULL&&relu!=baza) relu=relu->b;
        if(relu->fiu[ca]!=NULL) relu=relu->fiu[ca];
        if(relu!=baza) relu->sol++;
    }
    dfs(baza);
    for(h=1;h<=t;h++)
        solve(0, baza);
    fin.close();
    fout.close();
    return 0;
}