Cod sursa(job #2921102)

Utilizator UnknownPercentageBuca Mihnea-Vicentiu UnknownPercentage Data 27 august 2022 14:42:55
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define vt vector
#define pb push_back
#define em emplace
#define emb emplace_back

#define all(x) x.begin(), x.end()
#define all1(x) x.begin() + 1, x.end()
#define sz(x) (int)(x).size()

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template <class T> void re(vt <T>& x);
template <class T> void re(T& x) {
    cin >> x;
}

template <class H, class... T> void re(H &x, T&... y) {
    re(x); re(y...);
}

template <class T> void re(vt <T>& x) {
    for(auto& it : x)
        re(it);
}

template <class T> void wr(T x) {
    cout << x;
}

template <class H, class ...T> void wr(H x, T... y) {
    wr(x); wr(y...);
}

inline void Open(const string Name) {
    #ifndef ONLINE_JUDGE
        (void)!freopen((Name + ".in").c_str(), "r", stdin);
        (void)!freopen((Name + ".out").c_str(), "w", stdout);
    #endif
}

int Fin[101];
int ic, sc;

struct ac {
    int nr;
    vt <int> d;
    ac *f[26], *fail;
    ac() {
        d.clear();
        nr = 0;
        memset(f, 0x00, sizeof(f));
        fail = nullptr;
    }
} *q[26 * 10001], *t, *p;

void ins(ac* t, const string p, int pos, int idx) {
    if(pos == sz(p)) {
        t -> d.emb(idx);
        return;
    }

    int nxt = p[pos] - 'a';
    if(t -> f[nxt] == 0) t -> f[nxt] = new ac;
    ins(t -> f[nxt], p, pos + 1, idx);
}

void bfs(ac* t) {
    ac* dolar;
    t -> fail = t;

    for(q[ic = sc = 1] = t;ic <= sc;ic++) {
        ac* fr = q[ic];
        for(int i = 0;i < 26;i++)
            if(fr -> f[i] != nullptr) {
                for(dolar = fr -> fail;dolar != t && dolar -> f[i] == nullptr;dolar = dolar -> fail);
                
                if(dolar -> f[i] != nullptr && dolar -> f[i] != fr -> f[i])
                    dolar = dolar -> f[i];
                fr -> f[i] -> fail = dolar;
                q[++sc] = fr -> f[i];
            }
    }
    t -> fail = nullptr;
}

void antibfs(ac* t) {
    for(int i = sc;i;i--) {
        ac* fr = q[i];
        if(fr -> fail != nullptr) fr -> fail -> nr += fr -> nr;
        for(int j = 0;j < sz(fr -> d);j++)
            Fin[fr -> d[j]] = fr -> nr;
    }
}

void solve() {
    string str; re(str);
    int n; re(n);
    t = new ac;
    for(int i = 1;i <= n;i++) {
        string s; re(s);
        ins(t, s, 0, i);
    }

    bfs(t);
    p = t;
    for(int i = 0;i < sz(str);i++) {
        int nxt = str[i] - 'a';
        for(;p -> f[nxt] == nullptr && p != t;p = p -> fail);
        if(p -> f[nxt] != nullptr) 
            p = p -> f[nxt];
        ++p -> nr;
    }
    antibfs(t);
    for(int i = 1;i <= n;i++)
        wr(Fin[i], '\n');
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    Open("ahocorasick");

    int t = 1;
    for(;t;t--) {
        solve();
    }

    return 0;
}