Cod sursa(job #1519923)

Utilizator timicsIoana Tamas timics Data 8 noiembrie 2015 05:34:51
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 2.34 kb
#include<fstream>
#include<iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define pb push_back
using namespace std;
char s[1000100], t[10100]; 
int N, r1[10100],r[10100];
queue<int> Q;
vector<int> sol, w[10100];

struct Trie {
    int cnt, nrc, ind;
    Trie *q[26];
    Trie *f;
    Trie(int x) {
        cnt = nrc = 0;
        ind = x;
        for(int i=0;i<26;++i) {
            q[i] = 0;
        }
        w[ind].pb(ind);
    }
};
Trie *T = new Trie(0);

vector<Trie*> v; 

void ins(Trie *nod, char *s) {
    if(*s=='\n') {
        sol.pb(nod->ind);
        ++nod->cnt;
        return;
    }
    if(nod->q[*s-'a']==0) {
        Trie *nt = new Trie(v.size());
        v.pb(nt);
        nod->q[*s-'a'] = nt;
        ++nod->nrc;
    }
    ins(nod->q[*s-'a'],s+1);
}

void make_fail() {
    for(int i=0;i<26;++i) {
        if(v[0]->q[i] == 0) continue;
        Trie *y = v[0]->q[i];
        Q.push(y->ind);
        y->f = v[0];
    }
    while(!Q.empty()) {
        int x = Q.front();
        Q.pop();
        for(int i=0;i<26;++i) {
            if(v[x]->q[i] == 0) continue; 
            Trie *y = v[x]->q[i];
            Trie *curr = v[x]->f;
            while(curr != 0 && curr->q[i] == 0) {
                curr = curr->f;
            }
            if(curr == 0) {
                y->f = v[0];
            } else {
                y->f = curr->q[i];
            }
            for(auto j: w[y->f->ind]) {
                w[y->ind].pb(j);
            }
            Q.push(y->ind);
        }
    }
}

void do_magic() {
    int L = strlen(s);
    Trie *curr = v[0];
    for(int i=0;i<L;++i) {
        int c = s[i]-'a';
        while(curr != 0 && curr->q[c] == 0) {
            curr = curr->f;
        }
        if(curr == 0) {
            curr = v[0];
        } else {
            ++r1[curr->q[c]->ind];
            curr = curr->q[c];
        }
    }
    for(int i=1;i<v.size();++i) {
        for(int j=0;j<w[i].size();++j) {
            r[w[i][j]] += r1[i];
        }
    }
}

int main() {
 	//freopen("input.in","r",stdin);
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    scanf("%s%d",s,&N);
    v.pb(T);
    for(int i=1;i<=N;++i) {
        scanf("%s",t);
        t[strlen(t)] = '\n';
        ins(T,t);
    }
    make_fail();
    do_magic();  
    for(auto x: sol) {
        printf("%d\n",r[x]);
    }
    return 0;
}