暑假集训day9补充(AC自动机)

推荐网站http://blog.csdn.net/niushuai666/article/details/7002823

AC自动机嘛,此AC(aho-corasick)非彼AC(Accepted)。

我也不是很会解释

有一题是必须打的hdu2222。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int mn=500010;
int ch[mn][26],siz,ro,val[mn],last[mn],f[mn];
int newnode(){
    memset(ch[siz],0,sizeof(ch[siz]));val[siz]=0;
    return siz++;
}
void init(){
    siz=1;ro=newnode();
}
void add(char *s){
    int u=ro,l=strlen(s);
    for(int i=0;i<l;i++){
        int c=s[i]-‘a‘;
        if(ch[u][c]==0)ch[u][c]=newnode();
        u=ch[u][c];
    }
    val[u]++;
}
void getfail(){
    queue<int>q;last[ro]=f[ro]=ro;
    for(int i=0;i<26;i++){
        int x=ch[ro][i];
        if(!x)ch[ro][i]=ro;
        else{q.push(x);f[x]=last[x]=ro;}
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=0;i<26;i++){
            int v=ch[u][i];
            if(!v)ch[u][i]=ch[f[u]][i];
            else{
                q.push(v);f[v]=ch[f[u]][i];
                if(val[f[v]])last[v]=f[v];
                else last[v]=last[f[v]];
            }
        }
    }
}
int match(char *s){
    int u=ro,ans=0,l=strlen(s);
    for(int i=0;i<l;i++){
        u=ch[u][s[i]-‘a‘];
        int tmp=u;
        while(tmp!=ro){
            ans+=val[tmp];
            val[tmp]=0;
            tmp=last[tmp];
        }
    }
    return ans;
}
char text[1000010];
int main(){
    int T;scanf("%d",&T);
    while(T--){
        int n;scanf("%d",&n);init();
        for (int i=0;i<n;i++){
            scanf("%s",text);add(text);
        }
        getfail();scanf("%s",text);
        printf("%d\n",match(text));
    }
    return 0;
}

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

时间: 2024-12-17 13:06:07

暑假集训day9补充(AC自动机)的相关文章

暑假集训day9

今天主要将讲与字符串有关的吧. 1.trie树 Remember the Word(LA_3942) trie树的模板题了.如果trie树不知道可以看蓝书(算法竞赛入门经典第一版)(以下的KMP和AC自动机都可以在此书上看到). #include<cstring> #include<vector> #include<cstdio> #include<iostream> using namespace std; const int mn=400010,mod=

【暑假】[实用数据结构] AC自动机

Aho-Corasick自动机 AC自动机用于解决文本一个而模板有多个的问题. 作者所给模板如下: 1 struct AhoCorasickAutomata { 2 int ch[MAXNODE][SIGMA_SIZE]; 3 int f[MAXNODE]; // fail函数 4 int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val 5 int last[MAXNODE]; // 输出链表的下一个结点 6 int cnt[MAXS]; 7 int sz; 8 9

暑假 D6 T1 substring(AC自动机)

题目描述 给出一个长度为n的文本串,有Q次询问,每次给出一个字符串S,询问S是否在文本串中出现过 输入格式 第一行为两个整数n和Q,分别表示文本串长度和询问次数 第二行为长为n的文本串 接下来Q行,每行为一个字符串S 输出格式 输出Q行对应Q次询问的答案,若出现过则输出YES,否则输出NO 数据范围 对于100%的数据n,Q≤100000,且保证S为长度不超过100000的回文串,且所有的S的总长不超过1000000,保证所有字符都是小写字母. 题解 昨天才做了阿狸的打字机,就想到是一样的,而且

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

暑假集训结束

暑假集训结束了!!! 说实话其实还是有些遗憾的,我没有和同学一起去诸暨集训,但是我还是很高兴,我的同学将试题都发给了我,以至于我没有落后太多,所以这里致谢机房其他4位大佬. 我重新翻了一下我的做题记录,虽然做题不多,但是至少每道题都有收益,于是想要总结一下. 6.16 期末考试告一段落 6.17 复习了并查集,知道了并查集记录链头和链长的方法P1196 6.18 继续研究DP,加深了树形DP,学习了悬线法,用此方法解决了以前乱搞的题 6.19 复习状压DP 6.20 pb学哥来讲课了,然后学习了

跳跃表,字典树(单词查找树,Trie树),后缀树,KMP算法,AC 自动机相关算法原理详细汇总

第一部分:跳跃表 本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈"跳跃表"的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代码,以及本人对其的了解.难免有错误之处,希望指正,共同进步.谢谢. 跳跃表(Skip List)是1987年才诞生的一种崭新的数据结构,它在进行查找.插入.删除等操作时的期望时间复杂度均为O(logn),有着近乎替代平衡树的本领.而且最重要的一点,就是它的编程复杂度较同类

POJ 4052 AC自动机

[题意]: 给你n个字符串和一个文本,问有多少个字符串满足如下条件:该字符串包含在文本,该字符串不为其它字符串的子串. [知识点]: Ac自动机,处理字符串 [题解]: 集训比赛的时候当时被题目的数据量吓到了,不敢用ac自动机.但在网上看到题解时,然后瞬间就感觉自己想多了... 很水的一道ac自动机处理字符串的题目,先将查询的字符做成字典树,然后在文本中查找字符串是否存在. 在处理去子串上,我的做法是查找文本时去除后缀相同的包含子串.然后单独在搜索剩余可用字符串前缀相同子串. [代码]: 1 #

ac自动机基本

今天研究了一下ac自动机,感觉学了些入门的知识,什么可持久化自动机.有限状态自动机,还有自动机上的DP还不是很懂.所以今天先贴基本代码,以后补充其他知识. 参考资料:http://blog.csdn.net/niushuai666/article/details/7002823.里面介绍很详细了,特别是构造fail指针那幅图特别经典.注意到KMP的有两种写法:第i位fail指针指向前面某个具有相同元素的最近位置j:或第i位fail指针指向前面最近的具有不同元素的位置j,但要求i-1与j-1元素相

【小结】AC自动机

参考资料:http://blog.csdn.net/niushuai666/article/details/7002823 搞了两天,突然明白,这玩意它原来就是个DFA鸭!窝来分析分析 从DFA到AC自动机: 考虑以下单词: {she, he, her},字母表∑为26个小写字母 我们先画出它Trie树的模样 注意,双圈的是包含单词结尾的位置.然后我们尝试将它稍加改造,变成一个DFA! 对每一个状态,必须补充下一个字母为其它(比如从起始状态出发,输入一个h,匹配上了,接下来输入可能为a-z,我们