AC-AC自动机


AC自动机.

struct AC {
    std::vector<std::array<int, 26>> nex, son;
    std::vector<int> fail;
    std::vector<std::array<int, 2>> cnt;  // time sum_of_len
    int idx;
    std::vector<int> dfn;
    AC(int size) : nex(size + 10), son(size + 10), fail(size + 10), cnt(size + 10), idx(1) {}
    void add(std::string &s) {
        int p = 0;
        for (auto i : s) {
            i -= 'a';
            if (!nex[p][i])
                nex[p][i] = idx++;
            p = nex[p][i];
        }
        cnt[p][0] = 1;
        cnt[p][1] = s.size();
    }
    void clean() {
        std::fill(nex.begin(), nex.begin() + idx, array<int, 26>());
        std::fill(son.begin(), son.end(), array<int, 26>());
        std::fill(fail.begin(), fail.begin() + idx, 0);
        std::fill(cnt.begin(), cnt.begin() + idx, 0);
        idx = 0;
    }
    void work() {
        std::queue<int> que;
        que.push(0);
        while (que.size()) {
            auto x = que.front();
            que.pop();
            dfn.push_back(x);
            cnt[x][0] += cnt[fail[x]][0], cnt[x][1] += cnt[fail[x]][1];
            for (int i = 0; i < 26; i++) {
                if (nex[x][i]) {
                    son[x][i] = nex[x][i];
                    if (x)
                        fail[nex[x][i]] = son[fail[x]][i];
                    que.push(nex[x][i]);
                } else
                    son[x][i] = son[fail[x]][i];
            }
        }
    }
    void get(std::string &s) {
        // by your self
    }
};

exp: P5357 【模板】AC 自动机

struct AC {
    std::vector<std::array<int, 26>> nex, son;
    std::vector<int> fail;
    std::vector<int> cnt;  // time
    int idx;
    std::vector<int> dfn;
    AC(int size) : nex(size + 10), son(size + 10), fail(size + 10), cnt(size + 10), idx(1) {}
    int add(std::string &s) {
        int p = 0;
        for (auto i : s) {
            i -= 'a';
            if (!nex[p][i])
                nex[p][i] = idx++;
            p = nex[p][i];
        }
        return p;
    }
    void clean() {
        std::fill(nex.begin(), nex.begin() + idx, array<int, 26>());
        std::fill(son.begin(), son.end(), array<int, 26>());
        std::fill(fail.begin(), fail.begin() + idx, 0);
        std::fill(cnt.begin(), cnt.begin() + idx, 0);
        idx = 0;
    }
    void work() {
        std::queue<int> que;
        que.push(0);
        while (que.size()) {
            auto x = que.front();
            que.pop();
            dfn.push_back(x);
            for (int i = 0; i < 26; i++) {
                if (nex[x][i]) {
                    son[x][i] = nex[x][i];
                    if (x)
                        fail[nex[x][i]] = son[fail[x]][i];
                    que.push(nex[x][i]);
                } else
                    son[x][i] = son[fail[x]][i];
            }
        }
    }
    void get(std::string &s) {
        int p = 0;
        for (auto i : s) {
            i -= 'a';
            p = son[p][i];
            cnt[p]++;
        }
        for (int i = idx; i >= 0; i--) {
            cnt[fail[dfn[i]]] += cnt[dfn[i]];
        }
    }
};

void solve() {
    AC ac(2e5 + 10);
    int n;
    cin >> n;
    vector<int> p;
    for (int i = 0; i < n; i++) {
        string s;
        cin >> s;
        p.push_back(ac.add(s));
    }
    ac.work();
    string s;
    cin >> s;
    ac.get(s);
    for (auto i : p) {
        cout << ac.cnt[i] << '\n';
    }
}
,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注