码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2222 - Keywords Search

时间:2017-08-10 01:12:35      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:void   mem   自动机   turn   its   highlight   memset   lap   name   

试个模板- -

/*
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\n", ac.ans);
    }
}

  

HDU 2222 - Keywords Search

标签:void   mem   自动机   turn   its   highlight   memset   lap   name   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!