HDU 2222 最简单的AC自动机套模板应用

HDU 2222 题意:给出N(N<=10,000)个单词,每个单词长度不超过50。再给出一个字符串S,字符串长度不超过1,000,000。问有多少个单词出现在了字符串S中。(单词可能重复,单词在S中允许重叠)

我们在val[]数组中记录重复的个数

因为在主串对他进行匹配时,匹配到一次后这个重复次数就不应该继续添加了,所以在query中val[]要对它进行清零操作

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 500005
char str[1000005];
struct AC{
    int ch[N][26],fail[N],val[N],last[N],tmp,root;
    int newnode(){
        val[tmp]=0;
        memset(ch[tmp],0,sizeof(ch[tmp]));
        return tmp++;
    }
    void init(){
        tmp=0;
        root=newnode();
    }
    void add(char *s){
        int len=strlen(s);
        int now=root;
        for(int i=0;i<len;i++){
            int &k=ch[now][s[i]-‘a‘];
            if(!k) k=newnode();
            now=k;
        }
        val[now]++;
    }
    void get_fail(){
        fail[root]=root;
        queue<int> q;
        for(int i=0;i<26;i++){
            int v=ch[root][i];
            if(v)
                fail[v]=last[v]=0,q.push(v);
        }
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                int v=ch[now][i];
                if(!v) ch[now][i]=ch[fail[now]][i];
                else{
                    fail[v]=ch[fail[now]][i];
                    last[v]=val[fail[v]]?fail[v]:last[fail[v]];
                    q.push(v);
                }
            }
        }
    }
    int query(char *str){
        int len=strlen(str);
        int now=root,ret=0;
        for(int i=0;i<len;i++){
            now=ch[now][str[i]-‘a‘];
            int k=now;
            while(k!=root&&val[k]){//这是要循环到找到fail值为root的时候或者找到匹配的字符串的时候,否则一直向前找fail值,
                ret+=val[k];
                val[k]=0;
                k=last[k];
            }
        }
        return ret;
    }
}ac;
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        ac.init();
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",str);
            ac.add(str);
        }
        ac.get_fail();
        scanf("%s",str);
        int ans=ac.query(str);
        printf("%d\n",ans);
    }
    return 0;
}

HDU 2222 最简单的AC自动机套模板应用

时间: 2024-10-10 16:48:54

HDU 2222 最简单的AC自动机套模板应用的相关文章

HDU 2222——Keywords Search(AC自动机)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 34020    Accepted Submission(s): 11009 Problem Description In the modern time, Search engine came into the life of everybody like

HDU 2222 Keywords Search 【AC自动机】

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=2222] 题意:给出很多小字符串,然后给出一个文本串,问文本串中包含多少个小字符串.也就是说如果文本串中出现了多次某个小字符串,则只算一次. 题解:裸的AC自动机,首先利用小字符串建立一个Trie,然后再Trie上做KMP,使得为一个节点具有一个fail指针,其含义是,当文本串在某个节点失配时,则在Trie上找到根节点到这个节点的最长后缀的一个串,然后指向它. 不断地匹配下去就行了. #includ

hdu 2222 Keywords Search(AC自动机入门)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 42138    Accepted Submission(s): 13289 Problem Description In the modern time, Search engine came into the life of everybody like

HDU 2222 Keywords Search(AC自动机模板题)

题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:因为有可能有重复的模板,trie树权值记录每个模板出现的次数即可. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map>

HDU 2222 Keywords Search (AC自动机)

题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同 AC自动机:trie树上进行KMP.首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在这一位不匹配时转移到失配指针上.失配指针是转移到某个等于此位置最长后缀的位置,求法是bfs #include<set> #include<map> #include<queue> #include<stack> #include<cmath> #in

HDU 2222 Keywords Search(AC自动机)

裸的AC自动机, 这倒题不能使用静态数组模拟建树的过程,10000*50*26这样会爆内存,所以使用指针,使用结构体动态分配new 这个可以用来做模板了 1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath>

HDU 2222 Keywords Search (初学AC自动机)

我是通过http://wenku.baidu.com/view/4e70ccc38bd63186bcebbcb9.html的第二篇学会的 这篇也总结的很好,附带很多经典的习题http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html 这是bin神的总结:http://www.cnblogs.com/kuangbin/p/3164106.html 这是kss的板子:http://paste.ubuntu.com/1049986

HDU 2222 Keywords Search(AC自己主动机模板题)

题意:给出一个字符串和若干个模板,求出在文本串中出现的模板个数. 思路:由于有可能有反复的模板,trie树权值记录每一个模板出现的次数就可以. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map&

HDU 2222 Keywords Search【AC自动机】

自写的板子,新鲜出炉,所以不保证没BUG,慎用 1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 const int maxn = 26; 7 struct Node{ 8 int mark; 9 Node *next[maxn]; 10 Node *fail; 11 Node(){ 12 mark =