Cod sursa(job #1606130)

Utilizator livliviLivia Magureanu livlivi Data 19 februarie 2016 22:04:15
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include<cstdio>
#include<vector>
#define SIGMA 26
#define LEN 1000000
#define N 100
using namespace std;

class trie{
public:
    int nrap;
    trie* fail;

    vector<int> nrc;
    trie* fiu[SIGMA];

    trie(){
        nrap=0;
        fail=NULL;
        for(int i=0;i<SIGMA;i++)
            fiu[i]=NULL;
    }

    void insert(char *s,int id){
        if (s[0]==NULL){
            this-> nrc.push_back(id);
        }
        else {
            int urm=s[0]-'a';

            if (this-> fiu[urm]==NULL) this-> fiu[urm]=new(trie);

            this-> fiu[urm]-> insert(s+1,id);
        }
    }
};

trie* T=new(trie);

trie* queue[LEN+1];
int ic,sf;

int cnt[N+1];

void bfs(){
    sf=1;
    queue[0]=T;

    for(ic=0;ic<sf;ic++){
        trie* crt=queue[ic];

        for(int i=0;i<SIGMA;i++){
            if (crt-> fiu[i]!=NULL){
                trie* p=crt-> fail;
                while(p->fiu[i]==NULL &&p!=T){
                    p=p-> fail;
                }

                if (p==T &&T-> fiu[i]==NULL) crt-> fiu[i]-> fail=T;
                else
                if (crt!=T) crt-> fiu[i]-> fail=p-> fiu[i];
                else crt-> fiu[i]-> fail=T;

                queue[sf]=crt-> fiu[i];
                sf++;
            }
        }
    }
}

char cuv[LEN+1];
int l;

void parc(){
    trie* p=T;

    for(int i=0;i<l;i++){
        int lit=cuv[i]-'a';

        while(p-> fiu[lit]==NULL &&p!=T) p=p-> fail;

        if (p-> fiu[lit]!=NULL) p=p-> fiu[lit];
        p-> nrap++;
    }
}

void antibfs(){
    for(sf--;sf>=0;sf--){
        trie* crt=queue[sf];

        crt-> fail-> nrap+= crt-> nrap;

        for(int i=0;i<crt-> nrc.size();i++)
            cnt[crt-> nrc[i]]+= crt-> nrap;
    }
}

int main(){
    freopen ("ahocorasick.in","r",stdin);
    freopen ("ahocorasick.out","w",stdout);
    int n,i;
    char s[10000];

    gets(cuv);
    scanf ("%d\n",&n);

    for(i=1;i<=n;i++){
        gets(s);

        T-> insert(s,i);
    }

    l=0;
    while(cuv[l]>='a' &&cuv[l]<='z') l++;

    T-> fail=T;
    bfs();
    parc();
    antibfs();

    for(i=1;i<=n;i++)
        printf ("%d\n",cnt[i]);

    return 0;
}