关闭

【模板】AC自动机(加强版) 洛谷3796 AC自动机

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

题目

有NN个由小写字母组成的模式串以及一个文本串TT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TT中出现的次数最多。

分析

改一改

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>

using namespace std;

struct Tree{
    int fail,from;
    int vis[26];
    int num;
}ac[1000000];
int n;
int cnt=0;

int w[1000000];
string ss[500];

void Build(string s,int x)
{
    int l=s.length();
    int now=0;
    for(int i=0;i<l;++i)
    {
        if(ac[now].vis[s[i]-'a']==0) ac[now].vis[s[i]-'a']=++cnt;
        now=ac[now].vis[s[i]-'a'];
    }
    ac[now].num+=1; 
    ac[now].from=x;
}

void Get_fail()
{
    queue<int> Q;
    for(int i=0;i<26;++i)
    {
        if(ac[0].vis[i]!=0)
        {
            ac[ac[0].vis[i]].fail=0;
            Q.push(ac[0].vis[i]);
        }
    }
    while(!Q.empty()) 
    {
        int u=Q.front();
        Q.pop();
        for(int i=0;i<26;++i)
        {
            if(ac[u].vis[i]!=0)
            {
                ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i];
                Q.push(ac[u].vis[i]);
            }
            else ac[u].vis[i]=ac[ac[u].fail].vis[i];
        }
    }
}

void ac_Query(string s)
{
    int l=s.length();
    int now=0,ans=0;
    for(int i=0;i<l;++i)
    {
        now=ac[now].vis[s[i]-'a'];
        for(int t=now;t&&(ac[t].num!=-1);t=ac[t].fail)
        {
            if (ac[t].from!=0) w[ac[t].from]++;
            //ac[t].num=-1;
        } 
    }
    for (int i=1;i<=n;i++)
    {
        if (w[i]>ans) ans=w[i];
    }
    printf("%d\n",ans);
    for (int i=1;i<=n;i++)
    {
        if (w[i]==ans) cout<<ss[i]<<endl;
    }
}

int main()
{
    scanf("%d",&n);
    while (n){
    memset(ac,0,sizeof(ac));
    memset(w,0,sizeof(w));
    cnt=0;
    w[0]=0;
    for(int i=1;i<=n;++i)
    {
        string s;
        cin>>s;
        ss[i]=s;
        Build(s,i);
    }
    ac[0].fail=0;
    Get_fail();
    string s;
    cin>>s;
    ac_Query(s);
    scanf("%d",&n);
    }
}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

ac自动机最详细的讲解,让你一次学会ac自动机。

在没学ac自动机之前,觉得ac自动机是个很神奇,很高深,很难的算法,学完之后发现,ac自动机确实很神奇,很高深,但是却并不难。 我说ac自动机很神奇,在于这个算法中失配指针的妙处(好比kmp算法中的...
  • creatorx
  • creatorx
  • 2017-05-02 19:51
  • 14484

AC自动机的简单Java实现

AC自动机主要实现多模式字符匹配的快速查找,相关知识点为: 1.trie树 2.KMP算法 代码有相关注释,如下: import java.util.ArrayList; import jav...
  • sqh201030412
  • sqh201030412
  • 2017-01-05 11:15
  • 1476

Trie、KMP、AC自动机小结

最近做了不字符串的题,做下小结吧~          首先是Trie(也叫前缀树),Trie的结构并不难理解,Trie是个树形结构,它的每条边对应一个字符,每个节点对应一个字符串的前缀(根节点对应空串...
  • qian99
  • qian99
  • 2014-02-05 21:58
  • 1398

【洛谷P3796】【模板】AC自动机(加强版)

题目描述有个由小写字母组成的模式串以及一个文本串。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串中出现的次数最多。输入输出格式输入格式: 输入含多组数据。每组数据的第一行为一个正整...
  • w_yqts
  • w_yqts
  • 2017-07-26 10:57
  • 104

洛谷 P3796 【模板】AC自动机(加强版)

题面传送门 题解 随便统计一下每个单词出现的次数 详见代码 #include #include #include #include #include using namespace std...
  • qq_35878547
  • qq_35878547
  • 昨天 07:28
  • 16

AC自动机模板【洛谷3796】

AC自动机的第三个模板 其实,个人觉得,目前我写的这三个不同的模板完全是可以合并在一起求解的。 只是,在这两个无关联的OJ上,同一个AC自动机都可以完成的问题被拆成了三道题而已。 因此,代码只需...
  • qq_30974369
  • qq_30974369
  • 2017-07-09 23:46
  • 146

【洛谷】3808 【模板】AC自动机(简单版)

题目传送门 终于看懂啦!终于学会了AC自动机啦!(Flag立起)写篇博客梳理一下自己的思路吧。 在文章的开头,必须先放上一些大佬的博客来压压场面:我选的当然是ZZK大佬,神犇传送门 然而AC自动机的原...
  • lyfsb
  • lyfsb
  • 2017-08-01 13:57
  • 146

AC自动机模板(【洛谷3808】)

题面题目背景这是一道简单的AC自动机模版题。用于检测正确性以及算法常数。为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。 题目描述给定n个模式串和1个文本串,求有多少个模式串在文本串...
  • qq_30974369
  • qq_30974369
  • 2017-07-06 15:40
  • 178

AC自动机模板(c++版和java版)

这是我第一次写博客,可能整理的不好,请大家见谅。         先发一些我最近在刷的AC自动机的题,模版题我就不发了。。初学的话,可以看一下 AC自动机算法 - 飘过的小牛 - 博客频道 - CSD...
  • No__stop
  • No__stop
  • 2013-05-15 16:42
  • 1570

hdu 2222 AC自动机模板题(指针版+数组版)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others...
  • u014086851
  • u014086851
  • 2015-08-27 17:48
  • 395
    个人资料
    • 访问:55940次
    • 积分:3207
    • 等级:
    • 排名:第12303名
    • 原创:234篇
    • 转载:6篇
    • 译文:2篇
    • 评论:289条