关闭

hdu2222

201人阅读 评论(0) 收藏 举报
分类:

AC自动机模板

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN = 240005;
const int MAXL = 1000005;   

struct ACM
{
    int ch[MAXN][26], cnt[MAXN], f[MAXN], last[MAXN], q[MAXN];
    int sz, h, r;
    void init()
    {   
        sz = 0;
        memset(ch, 0, sizeof(ch));
        memset(cnt, 0, sizeof(cnt));
    }
    void insert(char *s)
    {
        register int x = 0, d, i;
        for(i = 0; s[i]; ++i)
        {
            d = s[i] - 'a';
            if(!ch[x][d]) ch[x][d] = ++sz;
            x = ch[x][d];
        }
        ++cnt[x];
    }
    void build()
    {
        register int d, x, y, z, h, r;
        h = r = 0;
        f[0] = 0;
        for(d = 0; d < 26; ++d)
        {
            x = ch[0][d];
            if(x) f[x] = last[x] = 0, q[r++] = x;
        }
        while(h < r)
        {
            x = q[h++];
            for(d = 0; d < 26; ++d)
            {
                y = ch[x][d], z = f[x];
                if(!y) { ch[x][d] = ch[z][d]; continue; }
                q[r++] = y;
                while(z && !ch[z][d]) z = f[z];
                f[y] = ch[z][d];
                last[y] = cnt[f[y]] ? f[y] : last[f[y]];
            }
        }
    }
    void add(int j, int &ans)
    {
        while(j && cnt[j]) ans += cnt[j], cnt[j] = 0, j = last[j];
    }
    int find(char *s)
    {
        register int i, j, d, ans = 0;
        for(i = j = 0; s[i]; ++i)
        {
            d = s[i] - 'a', j = ch[j][d];
            if(cnt[j]) add(j, ans); else if(last[j]) add(last[j], ans);
        }
        return ans;
    }
}ac;

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    static char o[55], s[MAXL];
    register int i, T, n; scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n), ac.init();
        for(i = 1; i <= n; ++i)
        {
            scanf("%s", o);
            ac.insert(o);
        }
        ac.build();
        scanf("%s", s);
        printf("%d\n", ac.find(s));
    }

#ifndef ONLINE_JUDGE
    fclose(stdin), fclose(stdout);
#endif
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9074次
    • 积分:551
    • 等级:
    • 排名:千里之外
    • 原创:44篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    My friends
    文章分类