Cod sursa(job #1351321)

Utilizator UVS_Miriam_Piro_DianaFrumoasele si Bestialul UVS_Miriam_Piro_Diana Data 21 februarie 2015 10:48:27
Problema Aho-Corasick Scor 25
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
#include<fstream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
struct trie{
    trie *c[26],*tata;
    trie *fail;
    vector<trie*> to;
    vector<int> is;
    int f,fs,s;
    vector<int> F,FS,S;
    char id;
    trie(){
        tata=fail=NULL;f=s=fs=0;
        for(int i=0;i<='z'-'a';i++) c[i]=NULL;
        to.clear(),is.clear(),id='$';
    }
};
trie* R=new trie;
char A[1000002],B[10002];
int N,n,m,f[102];
vector<int> FF[10001];
queue<trie*> q;
void dfs(trie* n){
    if(!n->fs) q.push(n);
    for(vector<trie*>::iterator it=n->to.begin();it!=n->to.end();++it) dfs(*it);
}
int main(){
    in.getline(A+1,100001); n=strlen(A+1);
    in>>N; in.get();
    for(int i=1;i<=N;i++){
        in.getline(B+1,10001); m=strlen(B+1);
        trie* wh=R;
        for(int j=1;j<=m;j++){
            if(wh->c[B[j]-'a']) wh=wh->c[B[j]-'a'];
            else{
                trie* fiu=wh->c[B[j]-'a']=new trie;
                wh->to.push_back(fiu);
                fiu->tata=wh;
                fiu->id=B[j];
                wh=fiu;
            }
        }
        wh->is.push_back(i);
    }
    R->fail=R;
    for(vector<trie*>::iterator it=R->to.begin();it!=R->to.end();++it) q.push(*it);
    while(!q.empty()){
        trie* x=q.front(); q.pop();
        trie* y=x->tata->fail;
        while(y!=R && !y->c[x->id-'a']) y=y->fail;
        if(y->c[x->id-'a']) x->fail=y->c[x->id-'a'];
        else x->fail=y;
        if(x->fail==x) x->fail=x->tata;
        x->fail->fs++;
        for(vector<trie*>::iterator it=x->to.begin();it!=x->to.end();++it) q.push(*it);
    }
    trie* wh=R;
    for(int i=1;i<=n;i++){
        while(wh!=R && !wh->c[A[i]-'a']) wh=wh->fail;
        if(wh->c[A[i]-'a']) wh=wh->c[A[i]-'a'];
        wh->f++;
        wh->F.push_back(i);
    }
    dfs(R);
    while(!q.empty()){
        trie *x=q.front(); q.pop();
        x->s+=x->f;
            x->S.insert(x->S.end(),x->F.begin(),x->F.end());
        for(vector<int>::iterator it=x->is.begin();it!=x->is.end();++it){
            f[*it]+=x->s;
                FF[*it].insert(FF[*it].end(),x->S.begin(),x->S.end());
        }
        x->fail->s+=x->s;
            x->fail->S.insert(x->fail->S.end(),x->S.begin(),x->S.end());
        x->fail->fs--;
        if(!x->fail->fs) q.push(x->fail);
    }
    //for(int i=1;i<=N;i++) out<<f[i]<<'\n';
    for(int i=1;i<=N;i++){
        out<<FF[i].size()<<'\n';
        //for(vector<int>::iterator it=FF[i].begin();it!=FF[i].end();++it) out<<*it<<' ';out<<'\n';
    }
    return 0;
}