Cod sursa(job #1502159)

Utilizator 2chainzTauheed Epps 2chainz Data 14 octombrie 2015 11:45:40
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include<fstream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
char S[1000001],s[10001];
int N,K,id[101],ans[101];
struct aho{
    vector<aho*> v;
    char c;int k,m;
    aho *fail,*son[30];
    aho(){v.clear(),fail=NULL,c=k=m=0;for(char c='a';c<='z';c++)son[c-'a']=NULL;}
    inline aho* hson(char &c){
        return son[c-'a'];
    }
} *root;
vector<aho*> bf;
int push_dict(char s[]){
    aho *w=root,*ch;
    int ns=strlen(s);
    for(int i=0;i<ns;i++){
        ch=w->hson(s[i]);
        if(!ch){
            ch=new aho();
            ch->c=s[i];
            w->v.push_back(ch);
            w->son[s[i]-'a']=ch;
        }
        w=ch;
    }
    if(!w->k) w->k=++K;
    return w->k;
}
queue< pair<aho*,aho*> > q;
void fails_bfs(){
    pair<aho*,aho*> temp;
    aho *w=root,*tat;
    for(vector<aho*>::iterator it=w->v.begin();it!=w->v.end();it++) q.push(make_pair(w,*it));
    while(!q.empty()){
        temp=q.front(); q.pop();
        tat=temp.first,w=temp.second;
        w->fail=tat->fail;
        while(w->fail && !w->fail->hson(w->c)) w->fail=w->fail->fail;
        if(!w->fail) w->fail=root;
        else w->fail=w->fail->hson(w->c);
        for(vector<aho*>::iterator it=w->v.begin();it!=w->v.end();it++) q.push(make_pair(w,*it));
        bf.push_back(w);
    }
}
int main(){
    ifstream in("ahocorasick.in");
    ofstream out("ahocorasick.out");
    root=new aho(),root->c='$';
    in.getline(S,1000001);
    in>>N; in.get();
    for(int i=0;i<N;i++) in.getline(s,10001),id[i]=push_dict(s);
    fails_bfs();
    aho *w=root;
    int NS=strlen(S);
    for(int i=0;i<NS;i++){
        while(w && !w->hson(S[i])) w=w->fail;
        if(!w) w=root;
        else w=w->hson(S[i]);
        aho *t=w;
        t->m++;
    }
    for(vector<aho*>::iterator it=bf.end()-1;it!=bf.begin()-1;it--){
        w=*it;
        ans[w->k]+=w->m;
        w->fail->m+=w->m;
    }
    for(int i=0;i<N;i++) out<<ans[id[i]]<<'\n';
    return 0;
}