完全忘了AC自动机怎么写了qwq,更别说AC自动机上DP了。

今天就好好地学习字符串好了qwq

提一下AC自动机的时间复杂度——设n是模式串的个数,m是文本串的长度,l是模式串的平均长度,那么它的时间复杂度就是\(O(n+m)*l\)。

AC自动机上fail指针指向的点,从root到它代表的是其后缀。

简单版:给定一个文本串,和多个模式串。求有多少个模式串在文本串中出现过。qwqwq

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#define MAXN 1000010
using namespace std;
int cnt,n;
char s[MAXN];
struct tree{int fail,end,t[26];}ac[MAXN];
inline void build(char s[])
{
int len=strlen(s);
int now=0;
for(int i=0;i<len;i++)
{
if(!ac[now].t[s[i]-'a'])
ac[now].t[s[i]-'a']=++cnt;
now=ac[now].t[s[i]-'a'];
}
ac[now].end+=1;
}
inline void get_fail()
{
queue<int>q;
for(int i=0;i<=25;i++)
if(ac[0].t[i]!=0)
ac[ac[0].t[i]].fail=0,q.push(ac[0].t[i]);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(ac[u].t[i]!=0)
{
ac[ac[u].t[i]].fail=ac[ac[u].fail].t[i];
q.push(ac[u].t[i]);
}
else ac[u].t[i]=ac[ac[u].fail].t[i];
}
}
}
inline int ac_query(char s[])
{
int len=strlen(s);
int now=0,ans=0;
for(int i=0;i<len;i++)
{
int now=ac[now].t[s[i]-'a'];
for(int k=now;k&&ac[k].end!=-1;k=ac[k].fail)
ans+=ac[k].end,ac[k].end=-1;
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
build(s);
}
ac[0].fail=0;
get_fail();
scanf("%s",s);
printf("%d\n",ac_query(s));
}

加强版:给定一个文本串和许多模式串,问在文本串中出现次数最多的模式串?以及出现的次数。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define MAXN 1000010
using namespace std;
int cnt,n;
char s[1000][100],q[MAXN];
struct tree{int fail,end,t[26];}ac[MAXN];
struct Ans{int num,pos;}ans[MAXN];
inline bool cmp(struct Ans x,struct Ans y)
{
if(x.num!=y.num) return x.num>y.num;
else return x.pos<y.pos;
}
inline void clean(int x)
{
memset(ac[x].t,0,sizeof(ac[x].t));
ac[x].fail=ac[x].end=0;
}
inline void build(char s[],int num)
{
int len=strlen(s),now=0;
for(int i=0;i<len;i++)
{
if(ac[now].t[s[i]-'a']==0)
ac[now].t[s[i]-'a']=++cnt,clean(cnt);
now=ac[now].t[s[i]-'a'];
}
ac[now].end=num;
}
inline void get_fail()
{
queue<int>q;
for(int i=0;i<=25;i++)
{
if(ac[0].t[i]!=0)
ac[ac[0].t[i]].fail=0,q.push(ac[0].t[i]);
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(ac[u].t[i]!=0)
{
ac[ac[u].t[i]].fail=ac[ac[u].fail].t[i];
q.push(ac[u].t[i]);
}
else ac[u].t[i]=ac[ac[u].fail].t[i];
}
}
}
inline void ac_query(char s[])
{
int len=strlen(s),now=0;
for(int i=0;i<len;i++)
{
now=ac[now].t[s[i]-'a'];
for(int k=now;k;k=ac[k].fail)
ans[ac[k].end].num++;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(;;)
{
if(n==0) break;
cnt=0;
clean(0);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]);
ans[i].num=0,ans[i].pos=i;
build(s[i],i);
}
ac[0].fail=0;
get_fail();
scanf("%s",q);
ac_query(q);
sort(&ans[1],&ans[n+1],cmp);
printf("%d\n",ans[1].num);
int len=strlen(s[ans[1].pos]);
for(int i=0;i<len;i++) printf("%c",s[ans[1].pos][i]);
puts("");
for(int i=2;i<=n;i++)
{
if(ans[i].num==ans[1].num)
{
int lenth=strlen(s[ans[i].pos]);
for(int j=0;j<lenth;j++) printf("%c",s[ans[i].pos][j]);puts("");
}
else break;
}
scanf("%d",&n);
}
return 0;
}

luogu AC自动机(模板)的更多相关文章

  1. (模板)AC自动机模板

    模板1. 给出模式串和文本串,文本串长度小于1e6,模式串长度之和小于1e6,求文本串中有多少模式串出现. 题目链接:https://www.luogu.org/problem/P3808 AC co ...

  2. HDU 2222 AC自动机模板题

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...

  3. Match:Keywords Search(AC自动机模板)(HDU 2222)

    多模匹配 题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串. 经典AC自动机模板题,不多说. #include <iostream& ...

  4. HDU 3065 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...

  5. HDU 2896 (AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...

  6. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  7. HDU 2222 (AC自动机模板题)

    题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...

  8. hdu 2222 Keywords Search ac自动机模板

    题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...

  9. KMP与AC自动机模板

    HDU 1711 Number Sequence(KMP模板题) http://acm.hdu.edu.cn/showproblem.php?pid=1711 #include<bits/std ...

  10. HDU3695(AC自动机模板题)

    题意:给你n个字符串,再给你一个大的字符串A,问你着n个字符串在正的A和反的A里出现多少个? 其实就是AC自动机模板题啊( ╯□╰ ) 正着query一次再反着query一次就好了 /* gyt Li ...

随机推荐

  1. spring boot 项目打包到maven仓库供其它模块使用

    在对spring boot项目进行打包发布的时候发现其它spring boot项目服务真正引用使用该spring boot包中的类 需对打包插件做如下修改: <build> <plu ...

  2. spring data jpa删除的使用方式

    public interface UserRepository extends CrudRepository<User, Long> { Long deleteByLastname(Str ...

  3. win 10+ iis 10 部署.net core 1.1 web api

    今天上午部署了wcf,部署了好久,一直没有部署好,最后找到了dudu的部署方法,结果中午吃饭的时候成功了,这是链接:http://www.cnblogs.com/dudu/p/3328066.html ...

  4. 06002001单例模式C#实现版本

    书名:设计模式之禅 作者:秦小波 出版社:机械工业出版社 1 描述 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 2 UML类图 图1-1 单例模式类图 3 代码 Singleto ...

  5. Lamber算法 & SurfaceShader自定义光照

    [SurfaceShader自定义光照] 1.在pragma中添加自定义光照函数名:  #pragma surface surf BasicDiffuse 2.实现自定义光照函数.下面就是Lamber ...

  6. siebel简介

    定义公司架构.描述S应用架构.安装应用.配置S.自动化的业务规则.数据整合.不同环境如何整合. 一.介绍CRM 销售.Callcenter等 允许管理客户和联系人. 二.Using the web c ...

  7. MFC常用函数总结

    1.MFC编辑框.静态文本框相关的常用函数 <1>GetDlgItemText(ID ,str) 作用:从对话框中获取文本 第一个参数为要获取的编辑框(或者静态文本框.单选按钮等可以显示内 ...

  8. 平衡二叉树之AVL树

    AVL树(命名来源于作者姓名,Adelson-Velskii和Landis),即平衡二叉树,满足以下的条件: 1)它的左子树和右子树都是AVL树 2)左子树和右子树的高度差不能超过1 从条件1可能看出 ...

  9. etherboot无盘启动

    2001.10.30 吴峰光 本站提供对无盘启动的支持.本文就此作一简单介绍. 一.概述 无盘启动,更确切的说是网络启动,可算是最为轻松和简便的启动方式了. 目前还很少有人了解它,因为目前的软硬件条件 ...

  10. qmake not exec in ubuntu

    Description Today, I want to run qmake command in terminal, but, it has error message such qmake: co ...