Cod sursa(job #1293286)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 15 decembrie 2014 18:17:01
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;

const int amax = 1000005;
const int smax = 10005;
const int nmax = 105;

int A, n, m, i, l, L, R;
int sol[nmax];
char a[amax], s[smax];

struct trie
{
    vector<int> v;
    int count;
    trie *f[26];
    trie *fail;

    trie()
    {
        v.resize(0);
        count = 0;
        memset(f, 0, sizeof(f));
        fail = NULL;
    }
};

trie *root = new trie;
trie *q[smax*nmax];
trie *where, *x, *y;

void insert(trie *t, int poz)
{
    if(poz == m)
    {
        t->v.pb(i);
        return;
    }
    l = s[poz] - 'a';
    if(!t->f[l]) t->f[l] = new trie;
    insert(t->f[l], poz + 1);
}

void read()
{
    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);

    scanf("%s", a);
    A = strlen(a);

    scanf("%d", &n);
    for(i = 1; i <= n; i++)
    {
        scanf("%s", s);
        m = strlen(s);
        insert(root, 0);
    }
}

void bfs()
{
    root->fail = root;
    L = R = 1;
    q[L] = root;

    while(L <= R)
    {
        x = q[L++];
        for(i = 0; i < 26; i++)
            if(x->f[i] != NULL)
            {
                y = x->f[i];
                for(where = x->fail; where != root && where->f[i] == NULL; where = where->fail);

                if(where->f[i] != NULL && where->f[i] != y)
                    where = where->f[i];

                y->fail = where;
                q[++R] = y;
            }
    }
}

void go()
{
    x = root;
    for(i = 0; i < A; i++)
    {
        l = a[i] - 'a';
        while(x->f[l] == NULL && x != root)
            x = x->fail;

        if(x->f[l] != NULL)
            x = x->f[l];

        x->count++;
    }
}

void anti_bfs()
{
    for(i = R; i >= 1; i--)
    {
        x = q[i];
        x->fail->count += x->count;

        for(auto it : x->v)
            sol[it] += x->count;
    }
}

void print()
{
    for(i = 1; i <= n; i++)
        printf("%d\n", sol[i]);
}

int main()
{
    read();
    bfs();
    go();
    anti_bfs();
    print();

    return 0;
}