Cod sursa(job #3194536)

Utilizator Mircea_DonciuDonciu Mircea Mircea_Donciu Data 18 ianuarie 2024 14:25:52
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <fstream>
#include <queue>
using namespace std;
int n,poz,k,ord[1000005],ras[105];
char CH[1000005],ch[10005];
struct aho{
    int copii[26],tt, bck, ap;
    char c;
}v[1000005];
queue <int> q;
int main()
{
    ifstream cin("ahocorasick.in");
    ofstream cout("ahocorasick.out");
    cin>>CH;
    cin>>n;
    //initializam arborele
    for(int i=0; i<26; i++) v[0].copii[i]=1;
    v[1].tt=0;
    v[1].bck=0;
    v[1].c='a';
    k=1; //nr de noduri
    //1 e nodul vid, 0 e un stramos al sau imaginar
    for(int i=1; i<=n; i++)
    {
        cin>>ch;
        poz=1;
        int j=0;
        while(ch[j])
        {
            if(v[poz].copii[ch[j]-'a'])
            {
                poz=v[poz].copii[ch[j]-'a'];
            }
            else
            {
                k++;
                v[k].tt=poz;
                v[poz].copii[ch[j]-'a']=k;
                v[k].c=ch[j];
                poz=k;
            }
            ch[j]=0;
            j++;
        }
        ras[i]=poz;
    }
    //acum aflam bck-ul
    for(int i=0; i<26; i++)
    if(v[1].copii[i])
        q.push(v[1].copii[i]);
    ord[0]=1;
    ord[1]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        ord[0]++;
        ord[ord[0]]=x;
        //aflam bck-ul lui x
        int y=v[x].tt;
        y=v[y].bck;
        while(v[y].copii[v[x].c-'a']==0)
        {
            y=v[y].bck;
        }
        v[x].bck=v[y].copii[v[x].c-'a'];
        for(int i=0; i<26; i++)
        if(v[x].copii[i])
            q.push(v[x].copii[i]);
    }
    int i=0;
    poz=1;
    while(CH[i])
    {
        //adaugam CH[i]-'a'
        while(v[poz].copii[CH[i]-'a']==0) poz=v[poz].bck;
        poz=v[poz].copii[CH[i]-'a'];
        v[poz].ap++;
        i++;
    }
    int sum=0;
    for(int i=ord[0]; i>=1; i--)
    {
        v[v[ord[i]].bck].ap+=v[ord[i]].ap;
    }
    /*for(int i=1; i<=k; i++)
    {
        cout<<i<<" are nr de aparitii "<<v[i].ap<<", tatal "<<v[i].tt<<" intoarcerea in: "<<v[i].bck<<" si copii:\n";
        for(int j=0; j<26; j++)
        if(v[i].copii[j])
        {
            char afis='a'+j;
            cout<<"    "<<afis<<": "<<v[i].copii[j]<<'\n';
        }
    }*/
    for(int i=1; i<=n; i++)
    {
        cout<<v[ras[i]].ap<<'\n';
    }
    return 0;
}