Cod sursa(job #2417317)

Utilizator flaviu_2001Craciun Ioan-Flaviu flaviu_2001 Data 29 aprilie 2019 15:14:36
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>
#define ff first
#define ss second

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;

const string file = "ahocorasick";
const ll INF = 9223372036854775807ll;
const int inf = 2147483647;

struct trie{
    trie *f[26], *fail;
    int occ;
    vector<int> v;
    trie(){
        memset(f, 0, sizeof(f));
        fail = 0;
        occ = 0;
    }
};

int n;
string r;
vector<string> e;
vector<int> ans;
trie *rad = new trie;

void add(trie *&t, int s, unsigned p)
{
    if(p == e.back().length())
        t->v.push_back(s);
    else{
        int q = e.back()[p]-'a';
        if(t->f[q] == NULL)
            t->f[q] = new trie;
        add(t->f[q], s, p+1);
    }
}

int main()
{
    ifstream fin (file+".in");
    ofstream fout (file+".out");
    fin >> r >> n;
    for (int i = 0; i < n; ++i){
        string s;
        fin >> s;
        e.push_back(s);
        ans.push_back(0);
        add(rad, i, 0);
    }
    vector<trie*> q;
    int p = -1;
    q.push_back(rad);
    rad->fail = rad;
    while(p+1 != q.size()){
        trie *t = q[++p];
        for (int i = 0; i < 26; ++i)
            if(t->f[i] != NULL){
                q.push_back(t->f[i]);
                t->f[i]->fail = t->fail;
                while(t->f[i]->fail != rad && t->f[i]->fail->f[i] == NULL)
                    t->f[i]->fail = t->f[i]->fail->fail;
                if(t->f[i]->fail->f[i] != NULL && t->f[i]->fail->f[i] != t->f[i])
                    t->f[i]->fail = t->f[i]->fail->f[i];
            }
    }
    trie *t = rad;
    for (int i = 0; i < r.length(); ++i){
        int u = r[i]-'a';
        while(t != rad && t->f[u] == NULL)
            t = t->fail;
        if(t->f[u] != NULL)
            t = t->f[u];
        ++t->occ;
    }
    for (int i = q.size()-1; i >= 0; --i){
        if(q[i]->fail != NULL)
            q[i]->fail->occ += q[i]->occ;
        for (auto x : q[i]->v)
            ans[x] = q[i]->occ;
    }
    for (int i = 0; i < n; ++i)
        fout << ans[i] << "\n";
    return 0;
}