Cod sursa(job #2763835)

Utilizator valentinchipuc123Valentin Chipuc valentinchipuc123 Data 17 iulie 2021 03:27:09
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb

#include <bits/stdc++.h>

using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
struct node {
    node* to[26]; node* lps; int nr;
    node() {memset(to, NULL, sizeof(to)); lps = NULL; nr = 0;}
    node* go_to(char ch) { if(!to[ch - 'a']) return to[ch - 'a'] = new node(); return to[ch - 'a']; }
};
class trie {
private:
    vector <node*> t, nodes;
    int k, n;
public:
    node* root = new node();
    void build(vector <string>& v) {
        root -> lps = root; n = (int)v.size();
        for(auto s : v) {
            node* curr = root;
            for(auto ch : s) curr = curr -> go_to(ch);
            t.push_back(curr);
        }
        node* aux; nodes.push_back(root); k = 0;
        while(k < (int)nodes.size()) {
            //cerr << k << " ";
            node* top = nodes[k++];
            for(short ch = 0; ch < 26; ch++) if(top -> to[ch]) {
                for(aux = top -> lps; aux != root && !aux -> to[ch]; aux = aux -> lps);
                //cerr << "Entered if for ch " << ch << "\n";
                if(aux -> to[ch] && aux != top) top -> to[ch] -> lps = aux -> to[ch];
                else top -> to[ch] -> lps = root;
                nodes.push_back(top -> to[ch]);
            }
        }
    }
    vector <int> solve(string s) {
        int len = s.length(); node* sn = root;
        for(int i = 0; i < len; i++) {
            short ch = s[i] - 'a';
            for(; sn != root && !sn -> to[ch]; sn = sn -> lps);
            if(sn -> to[ch]) sn = sn -> to[ch];
            sn -> nr++;
        }
        for(int i = k - 1; i >= 0; i--) nodes[i] -> lps -> nr += nodes[i] -> nr;
        vector <int> res(n);
        for(int i = 0; i < n; i++) res[i] = t[i] -> nr;
        return res;
    }
};
string s;
vector <string> dict;
int n;

int main()
{
    fin >> s;
    fin >> n; dict.resize(n);
    for(int i = 0; i < n; i++) fin >> dict[i];
    trie T; T.build(dict);
    vector <int> sol = T.solve(s);
    for(int i = 0; i < n; i++) fout << sol[i] << "\n";
    return 0;
}