HDU 2222

试个模板- -

/*
HDU 2222 - Keywords Search [ AC自动机 ]
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
const int SIZE = 26;
struct Trie {
    int ch[N][SIZE];
    int f[N], last[N], cnt[N], val[N];
    int tot, ans;
    void init() {
        tot = 0;
        memset(ch, 0, sizeof(ch));
        memset(val, 0, sizeof(val));
    }
    int ord(char c) {
        return c-'a';
    }
    void insert(char* s) {
        int now = 0, n = strlen(s);
        for (int i = 0; i < n; i++) {
            int t = ord(s[i]);
            if (!ch[now][t]) ch[now][t] = ++tot;
            now = ch[now][t];
        }
        val[now]++;
    }
    void getFail() {
        queue<int> Q;
        f[0] = 0;
        for (int t = 0; t < SIZE; t++) {
            int now = ch[0][t];
            if (now) {
                f[now] = last[now] = 0;
                Q.push(now);
            }
        }
        while (!Q.empty()) {
            int k = Q.front(); Q.pop();
            for (int t = 0; t < SIZE; t++) {
                int now = ch[k][t];
                if(!now) continue;
                Q.push(now);
                int nxt = f[k];
                while (nxt && !ch[nxt][t]) nxt=f[nxt];
                f[now] = ch[nxt][t];
                last[now] = val[f[now]] ? f[now] : last[f[now]];
            }
        }
    }
    void add(int now) {
        for (; now; now = last[now]) ans += val[now], val[now] = 0;
    }
    void Find(char* s) {
        int now = 0, n = strlen(s);
        ans = 0;
        for (int i = 0; i < n; i++) {
            int t = ord(s[i]);
            while (now && !ch[now][t]) now = f[now];
            now = ch[now][t];
            if (val[now]) add(now);
            else if (last[now]) add(last[now]);
        }
    }
}ac;
char s[1000005];
int main()
{
    int t; scanf("%d", &t);
    while (t--)
    {
        ac.init();
        int n; scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            ac.insert(s);
        }
        ac.getFail();
        scanf("%s", s);
        ac.Find(s);
        printf("%d
", ac.ans);
    }
}

 

#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
struct Tire {
    int ch[N][26], f[N], tot;
    int val[N], vis[N];
    void init() {
        tot = 0;
        memset(ch, 0, sizeof(ch));
        memset(f, 0, sizeof(f));
        memset(val, 0, sizeof(val));
    }
    int ord(char c) {
        return c - 'a';
    }
    void insert(char* s) {
        int now = 0, n = strlen(s);
        for (int i = 0; i < n; i++)
        {
            int t = ord(s[i]);
            if (!ch[now][t]) ch[now][t] = ++tot;
            now = ch[now][t];
        }
        val[now]++;
    }
    void buildFail()
    {
        queue<int> Q;
        f[0] = 0;
        for (int t = 0; t < 26; t++) {
            int now = ch[0][t];
            if (now) {
                Q.push(now);
                f[now] = 0;
            }
        }
        while (!Q.empty()) {
            int now = Q.front(); Q.pop();
            for (int t = 0; t < 26; t++) {
                int v = ch[now][t];
                if (!v) {ch[now][t] = ch[f[now]][t]; continue; }
                Q.push(v);
                int nxt = f[now];
                while (nxt && !ch[nxt][t]) nxt = f[nxt];
                f[v] = ch[nxt][t];
            }
        }
    }
    int Find(char *s) {
        int ans = 0;
        int n = strlen(s), now = 0;
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < n; i++)
        {
            int t = ord(s[i]);
          //  while (now && !ch[now][t]) now = f[now];
            now = ch[now][t];
            int tmp = now;
            while (tmp)
            {
                if (vis[tmp]) break;
                vis[tmp] = 1;
                ans += val[tmp];
                val[tmp] = 0;
                tmp = f[tmp];
            }
        }
        return ans;
    }
}ac;
char s[1000005];
int t, n;
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        ac.init();
        while (n--)
        {
            scanf("%s", s);
            ac.insert(s);
        }
        ac.buildFail();
        scanf("%s", s);
        printf("%d
", ac.Find(s));
    }
}

  

 

原文地址:https://www.cnblogs.com/nicetomeetu/p/7336897.html