Cod sursa(job #1975798)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 1 mai 2017 23:48:28
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <bits/stdc++.h>
using namespace std;

ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");

struct nod{
    nod *fii[26] = {}, *suffix = nullptr;
    int nr_treceri = 0; };

nod *add_fiu(nod *n, const char ch){
    if(!n->fii[ch-'a']) n->fii[ch-'a'] = new nod {};
    return n->fii[ch-'a']; }

nod *add_string(nod *n, const string& str){
    for(const auto x : str) n = add_fiu(n, x);
    return n; }

vector<nod*> by_depth[(int)1e4 + 100] = {};

void by_depth_dfs(nod *n, const int depth = 0){
    by_depth[depth].push_back(n);
    for(int i = 0; i < 26; ++i)
        if(n->fii[i])
            by_depth_dfs(n->fii[i], depth+1); }

void do_sons_suffix(nod *tata){
    for(int ch = 0; ch < 26; ++ch){
        if(!tata->fii[ch]) continue;
        nod *fiu = tata->fii[ch];
        fiu->suffix = tata->suffix;
        while(!fiu->suffix->fii[ch] && fiu->suffix != fiu->suffix->suffix)
            fiu->suffix = fiu->suffix->suffix;
        if(fiu->suffix->fii[ch] && fiu->suffix->fii[ch] != fiu) fiu->suffix = fiu->suffix->fii[ch]; } }

nod *advance_with_ch(nod *n, const char ch){
    while(!n->fii[ch-'a'] && n != n->suffix) n = n->suffix;
    if(n->fii[ch-'a']) n = n->fii[ch-'a'];
    return n; }

char buf[256], *p = buf;

int main(){
    string str;
    f >> str;
    int n;
    f >> n;

    nod *rad = new nod {};
    rad->suffix = rad;

    vector<nod*> important(n);
    for(auto& x : important){
        string ss;
        f >> ss;
        x = add_string(rad, ss); }

    by_depth_dfs(rad);
    for(auto& x : by_depth)
        for(auto& y : x)
            do_sons_suffix(y);

    nod *cur = rad;

    for(const auto x : str){
        cur = advance_with_ch(cur, x);
        ++cur->nr_treceri; }

    reverse(begin(by_depth), end(by_depth));
    for(auto& x : by_depth)
        for(auto& y : x)
            y->suffix->nr_treceri += y->nr_treceri;

    for(const auto n : important) g << n->nr_treceri << '\n';
    return 0; }