Cod sursa(job #2446692)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 10 august 2019 14:24:38
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>

/// nowruz

using namespace std;

struct ac {
    int sol;
    vector <int> id;
    ac *kids[26], *link;

    ac() {
        sol = 0;
        link = 0;
        for(int j = 0; j < 26; j++)
            kids[j] = 0;
    }

};

ac *root = new ac;

queue <ac*> q;
vector <ac*> ord;

int ans[107];

int main() {
    freopen("ahocorasick.in", "r", stdin);
    freopen("ahocorasick.out", "w", stdout);

    string pat;
    cin >> pat;
    int n;
    cin >> n;
    for(int j = 0; j < n; j++) {
        string s;
        cin >> s;
        ac *now = root;
        for(auto &ch : s) {
            int c = ch - 'a';
            if(now->kids[c] == 0)
                now->kids[c] = new ac;
            now = now->kids[c];
        }
        now->id.push_back(j + 1);
    }

    root->link = root;

    q.push(root);
    while(!q.empty()) {
        ac *now = q.front();
        ord.push_back(now);
        q.pop();
        for(int j = 0; j < 26; j++) {
            ac *nou = now->kids[j];
            if(nou) {
                ac *t = now;
                nou->link = root;
                while(t != root) {
                    t = t->link;
                    if(t->kids[j]) {
                        nou->link = t->kids[j];
                        break;
                    }
                }
                q.push(nou);
            }
        }
    }

    ac *now = root;
    int pos = -1;
    for(auto &ch : pat) {
        pos++;
        int c = ch - 'a';
        int cntroot = 0;
        while(1) {
            if(now->kids[c]) {
                now = now->kids[c];
                break;
            } else {
                if(now == root)
                    break;
                now = now->link;
            }
        }
        now->sol++;
    }

    for(int j = (int)ord.size() - 1; j >= 0; j--) {
        ac *now = ord[j];
        now->link->sol += now->sol;
        for(auto &i : now->id)
            ans[i] = now->sol;
    }

    for(int j = 1; j <= n; j++)
        printf("%d\n", ans[j]);

    return 0;
}