AC自动机

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
int T[400100][26] = {0};
int last[401000], f[410000], val[410000];
int sz = 0;
void     _Insert(string s){
    int u = 0;
    for (int i = 0; s[i]; i++){
        int c = s[i] - 'a';
        if (!T[u][c]){
            T[u][c] = ++sz;
            val[sz] = 0;
        }
        u = T[u][c];
    }
    val[u] ++;
}
char s[1000100];
void build(){
    queue<int> q;
    for (int i = 0; i < 26; i++){
        int u = T[0][i];
        if (u){
            f[u] = last[u] = 0;
            q.push(u);
        }
    }
    while (!q.empty()){
        int h = q.front(); q.pop();
        for (int i = 0; i < 26; i++){
            int u = T[h][i], v = f[h];
            if (!u){
                T[h][i] = T[v][i];
                continue;
            }
            q.push(u);
            while (v && !T[v][i]) v = f[v];
            f[u] = T[v][i];
            last[u] = val[f[u]] ? f[u] : last[f[u]];
        }
    }
}

long long sum = 0;
void print(int j){
    if (j){
        sum += val[j];
        val[j] = 0;
        print(last[j]);
    }
}
void aFind(){
    int j = 0;
    for (int i = 0; s[i]; i++){
        int c = s[i] - 'a';
        j = T[j][c];
        if (val[j]) print(j);
        else if (last[j]) print(last[j]);
    }
}

int main(){
    int t;
    cin>>t;
    while (t--){
        int n; cin>>n;
        memset(T, 0, sizeof(T));sz = 0;
        memset(last, 0 ,sizeof(last));
        memset(f, 0, sizeof (f));
        memset(val, 0, sizeof(val));
        for (int i = 0; i < n; i++){
            string a;
            cin>>a;
            _Insert(a);
        }
        build();
        scanf("%s", s);
        sum = 0;
        aFind();
        printf("%d\n", sum);
    }
}
时间: 2024-12-07 19:21:52

AC自动机的相关文章

HDU 2222 AC自动机

题意:给出多组模式串,再给出一个母串,问多少模式串是母串的字串. 裸AC自动机题,来试模板的. #include <iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<queue> using namespace std; char key[55],des[1000005]; const int MAX_NODE = 1000005; const in

hdu 2896 病毒侵袭 ac自动机

/* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本题中主要是计算每一个模式串 在主串中有没有出现过,而不是计算出现过多少次,所以将last[]数组省掉.... */ #include<algorithm> #include<iostream> #include<cstdio> #include<cstring>

字典树+KMP+AC自动机

                                                 <<字典树模板>> 1:字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种.用于统计,排序和保存大量的字符串(也可以保存其他的).优点就是利用公共的前缀来节约存储空间.在这举个简单的例子:比如说我们想储存3个单词,sky.skyline.skymoon.如果只是单纯的按照以前的字符数组存储的思路来存储的话,那么我们需要定义三个字符串数组.但是如果我们用字典树的话,只需

经典算法题每日演练——第八题 AC自动机

原文:经典算法题每日演练--第八题 AC自动机        上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那么它的时间复杂度为O(c*(m+n)),c:为模式串的个数.m:为模式串的长度,n:为正文的长度,那 么这个复杂度就不再是线性了,我们学算法就是希望能把要解决的问题优化到极致,这不,AC自动机就派上用场了.    其实AC自动机就是Trie树的一个活用,活用点就是灌输了kmp的思想,从

Aho-Corasick 多模式匹配算法、AC自动机详解

Aho-Corasick算法是多模式匹配中的经典算法,目前在实际应用中较多. Aho-Corasick算法对应的数据结构是Aho-Corasick自动机,简称AC自动机. 搞编程的一般都应该知道自动机FA吧,具体细分为:确定性有限状态自动机(DFA)和非确定性有限状态自动机NFA.普通的自动机不能进行多模式匹配,AC自动机增加了失败转移,转移到已经输入成功的文本的后缀,来实现. 1.多模式匹配 多模式匹配就是有多个模式串P1,P2,P3...,Pm,求出所有这些模式串在连续文本T1....n中的

HDU 3065 AC自动机

题意:给出大写字母组成的模式串,再给出一个字串匹配,问每个模式串在母串中出现的次数,母串为可见字符ASCII. 注意字典树开next的大小,没看清题MLE好几次.. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int kind = 28; int num[1

HDU 2896 AC自动机

题意:给出多组模式串,再给出多组母串,输出存在于母串中模式串的编号. #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int kind = 128; char str[10002],s[202]; int virus[10],vcnt; struct n

不算退役贴的退役贴

         就好像大二才学Java一样,这文章也是先写在记事本上的.本来得了铜牌还写退役贴确实没啥意思,但是看了看之前空间里那么幼稚的日志就发现不写点什么好像大学三年什么都没有做.其实写这东西确实不算是纪念ACM生涯的,嗯而是用来纪念一下我的大学的.          Txt没有换行,我又用了word...还记得高中自己不努力,放假就去银河战舰跟着大白,圆心那些人,就好像各自有各自事业一样的,我往死里玩头文字d3,玩的时候后面也有一群人看也挺骄傲嘛哈哈.          转眼间到了高考,

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford