zoukankan      html  css  js  c++  java
  • 【模板】AC自动机(简单版)

    题目背景

    通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名。

    这是一道简单的AC自动机模板题。

    用于检测正确性以及算法常数。

    为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。

    管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意

    题目描述

    给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

    输入格式

    第一行一个n,表示模式串个数;

    下面n行每行一个模式串;

    下面一行一个文本串。

    输出格式

    一个数表示答案

    输入输出样例

    输入 #1
    2
    a
    aa
    aa
    输出 #1
    2

    说明/提示

    subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;

    subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;

    这难度算简单版???我已经不想做加强版了

    所以可以简单的理解为将KMP放在Trie树上。

    注意如果每次跳fail边复杂度过高,一次存储完可以进行优化。

    这样的AC自动机就成为了Trie图。

    不懂Trie图的自行百度(我也是自学了40分钟才搞懂,感觉整个人要炸了)

    友情链接:https://www.cnblogs.com/cmmdc/p/7337611.html

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n,ch[5000005][30];
    
    int t,f[5000005],next[5000005];
    
    char s[1000005];
    
    inline void add(){
        int len=strlen(s+1),hhh=1;
        for(int i=1;i<=len;i++){
            int u=s[i]-'a';
            if(!ch[hhh][u]){
                ch[hhh][u]=++t;
            }
            hhh=ch[hhh][u];
        }
        f[hhh]++;
    }
    queue<int>q;
    
    inline void getnext(){
        for(int i=0;i<26;i++)ch[0][i]=1;
        next[1]=0;
        q.push(1);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                int u=ch[x][i];
                if(!u){
                    ch[x][i]=ch[next[x]][i];
                }
                else{
                    int p=next[x];
                    q.push(u);
                    next[u]=ch[p][i];
                }
            }
        }
    }
    
    inline int find(){
        int len=strlen(s+1);
        int i=1,hhh=1,q,w,ans=0;
        while(i<=len){
            q=s[i]-'a';
            w=ch[hhh][q];
            while(w>1){
                if(f[w]==-1){
                    break;
                }
                ans+=f[w];
                f[w]=-1;
                w=next[w];
            }
            hhh=ch[hhh][q];
            i++;
        }
        return ans;
    }
    int main(){
        scanf("%d",&n);
        t=1;
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            add();
        }
        getnext();
        scanf("%s",s+1);
        printf("%d
    ",find());
        return 0;
    } 
  • 相关阅读:
    Java中的数据类型
    java中变量的分类
    软考视频总结(二)——细化学习A
    软考视频总结(一)——蜕变
    Eclipse汉化
    IIS 服务或万维网发布服务,或者依赖这两种服务的某个服务未能启动。
    jQuery--编辑表格
    MVC之查询demo
    初识MVC之建项
    附加数据库 对于服务器 XXX失败
  • 原文地址:https://www.cnblogs.com/hrj1/p/11135456.html
Copyright © 2011-2022 走看看