Cod sursa(job #2199153)

Utilizator giotoPopescu Ioan gioto Data 26 aprilie 2018 19:08:09
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>
using namespace std;

int n;
int ans[105];
char s[10005];
char S[1000005];
struct Trie{
    int nr, cnt;
    vector <int> v;
    Trie *fiu[26];
    Trie *fail;
    Trie(){
        nr = 0;
        cnt = 0;
        v.clear();
        memset(fiu, NULL, sizeof(fiu));
        fail = NULL;
    }
};
Trie *T = new Trie();
inline void add(Trie *nod, char *s, int pos){
    if(*s == NULL){
        nod->cnt++;
        nod->v.push_back(pos);
        return ;
    }
    if(nod->fiu[*s - 'a'] == NULL) nod->fiu[*s - 'a'] = new Trie();
    add(nod->fiu[*s - 'a'], s + 1, pos);
}
vector <Trie*> q;
inline void bfs_fail(Trie *nod){
    nod->fail = nod;
    q.push_back(nod);
    for(int i = 0; i < q.size() ; ++i){
        nod = q[i];
        for(int i = 0; i < 26 ; ++i){
            if(nod->fiu[i] == NULL) continue ;
            Trie *gfail = nod->fail;
            Trie *it = nod->fiu[i];
            while(gfail != T && gfail->fiu[i] == NULL)
                gfail = gfail->fail;
            if(gfail->fiu[i] != NULL && gfail->fiu[i] != it)
                gfail = gfail->fiu[i];
            it->fail = gfail;
            q.push_back(it);
        }
    }
}
inline void parc(Trie *nod, char *s){
    if(*s == NULL) return ;
    while(nod != T && nod->fiu[*s - 'a'] == NULL)
        nod = nod->fail;
    if(nod->fiu[*s - 'a'] != NULL) nod = nod->fiu[*s - 'a'];
    nod->nr++;
    parc(nod, s + 1);

}
inline void bfs_rev(){
    for(int i = q.size() - 1; i >= 0 ; --i){
        Trie *nod = q[i];
        if(nod->fail != NULL) nod->fail->nr += nod->nr;
        for(auto it : nod->v) ans[it] = nod->nr;
    }
    return ;
}
int main()
{
    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);
    scanf("%s", S);
    scanf("%d", &n);
    for(int i = 1; i <= n ; ++i){
        scanf("%s", s);
        add(T, s, i);
    }
    bfs_fail(T);
    parc(T, S);
    bfs_rev();
    for(int i = 1; i <= n ; ++i)
        printf("%d\n", ans[i]);
    return 0;
}