HDU 2222 (AC自动机 板子题)

来源:互联网 发布:一个软件网络连接异常 编辑:程序博客网 时间:2024/05/16 11:35

题目链接:点击这里

AC自动机板子题

#include <bits/stdc++.h>using namespace std;#define maxn 511111#define maxm 1111111struct trie {    int next[maxn][26], fail[maxn], end[maxn];    int root, cnt;    int new_node () {        memset (next[cnt], -1, sizeof next[cnt]);        end[cnt++] = 0;        return cnt-1;    }    void init () {        cnt = 0;        root = new_node ();    }    void insert (char *buf) {//字典树插入一个单词        int len = strlen (buf);        int now = root;        for (int i = 0; i < len; i++) {            int id = buf[i]-'a';            if (next[now][id] == -1) {                next[now][id] = new_node ();            }            now = next[now][id];        }        end[now]++;    }    void build () {//构建fail指针        queue <int> q;        fail[root] = root;        for (int i = 0; i < 26; i++) {            if (next[root][i] == -1) {                next[root][i] = root;            }            else {                fail[next[root][i]] = root;                q.push (next[root][i]);            }        }        while (!q.empty ()) {            int now = q.front (); q.pop ();            for (int i = 0; i < 26; i++) {                if (next[now][i] == -1) {                    next[now][i] = next[fail[now]][i];                }                else {                    fail[next[now][i]] = next[fail[now]][i];                    q.push (next[now][i]);                }            }        }    }    int query (char *buf) {        int len = strlen (buf);        int now = root;        int res = 0;        for (int i = 0; i < len; i++) {            int id = buf[i]-'a';            now = next[now][id];            int tmp = now;            while (tmp != root) {                if (end[tmp]) {                    res += end[tmp];                    end[tmp] = 0;                }                tmp = fail[tmp];//沿着失配边走            }        }        return res;    }}ac;int n;char a[maxm];int main () {    int t;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        ac.init ();        for (int i = 1; i <= n; i++) {            scanf ("%s", a);            ac.insert (a);        }        ac.build ();        scanf ("%s", a);        printf ("%d\n", ac.query (a));    }    return 0;}
0 0