hdu2222 【AC自动机】Keywords Search

题意

给定n个模式串,求目标串中出现了多少个模式串。

传送门

思路

AC自动机模版题。

Code

#include <bits/stdc++.h>
 
using namespace std;
const int maxn = 1e6+10;
struct Ac {
    int tr[maxn][26], fail[maxn], e[maxn], cnt[maxn];
    int tot;
    void init() {
        memset(tr, 0, sizeof(tr));
        memset(e, 0, sizeof(e));
        memset(cnt, 0, sizeof(cnt));
        memset(fail, 0, sizeof(fail));
        tot=0;
    }
    void insert(char *t) {
        int p=0;
        for (int c, i=0; t[i]; ++i) {
            c = t[i]-'a';
            if(!tr[p][c]) tr[p][c] = ++tot;
            p=tr[p][c];
        }
        ++e[p];
    }
    void build() {
        queue<int>q;
        for (int i=0; i<26; ++i) {
            if(tr[0][i])
                q.push(tr[0][i]);
        }
        while(!q.empty()) {
            int u=q.front(); q.pop();
            for (int i=0; i<26; ++i) {
                if(tr[u][i]) fail[tr[u][i]]=tr[fail[u]][i], q.push(tr[u][i]);
                else tr[u][i]=tr[fail[u]][i];
            }
        }
    }
    int query(char *t) {
        int p=0, res=0;
        for (int i=0; t[i]; ++i) {
            p = tr[p][t[i]-'a'];
            for (int j=p; j && e[j]!=-1; j=fail[j]) {
                res += e[j];
                e[j]=-1;
            }
        }
        return res;
    }
}ac;
int n, T;
char str[maxn];
 
int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        ac.init();
        for (int i=1; i<=n; ++i) {
            scanf("%s", str);
            ac.insert(str);
        }
        scanf("%s", str);
        ac.build();
        printf("%d\n", ac.query(str));
    }
 
    return 0;
}
posted @ 2019-08-22 23:15  Acerkoo  阅读(109)  评论(0编辑  收藏  举报