https://www.cnblogs.com/gtarcoder/p/4820560.html

每个节点的后缀指针fail指针指向:

例如he,she,his,hers的例子(见蓝书P214):

7号点表示串his,将其头部去掉得到is但不存在该节点,再次将其头部去掉得到s,存在该节点,因此7号的后缀指针指向表示s的3号

5号点表示串she,将其头部去掉得到he,存在该节点,因此5号的后缀指针指向表示he的2号

从根节点到节点P可以得到一个字符串S,节点P的前缀指针定义为 指向树中出现过的S的最长后缀(不能等于S)

可以将trie上所有不存在的边u--(ch)-->v都补全为其fail指针指向的同类型边(f[u]--(ch)-->v'得到u--(ch)-->v')。(减少特判且方便递推)

每个节点的lst,与fail的区别在于,其指向的点表示的字符串一定是原来字符串集合中某一个完整的串(或空串),而fail则只要求原集合中某串的前缀即可

P3808中:由于只计算“出现过的”,所以某个算过贡献后要赋为0

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char *s[],tttt[],*sp=tttt,s2[];
int n;
//namespace AC
//{
// int ch[1001000][26],sum[1001000],f[1001000],root,mem,lst[1000100];
// void insert(char *x)
// {
// if(!root) root=++mem;
// int now=root,u;
// for(;*x;x++)
// {
// u=*x-'a';
// if(!ch[now][u]) ch[now][u]=++mem;
// now=ch[now][u];
// }
// sum[now]++;
// }
// void build()
// {
// int c,t,u,v;
// queue<int> q;
// f[root]=root;
// for(c=0;c<26;c++)
// {
// u=ch[root][c];
// if(u) {f[u]=root;q.push(u);lst[u]=root;}
// }
// while(!q.empty())
// {
// t=q.front();q.pop();
// for(c=0;c<26;c++)
// {
// u=ch[t][c];
// if(!u) {ch[t][c]=ch[f[t]][c];continue;}
// q.push(u);
// v=f[t];
// while(v!=root&&!ch[v][c]) v=f[v];
// f[u]=ch[v][c];
// lst[u]=sum[u]?f[u]:lst[f[u]];
// }
// }
// }
// void search(char *x)
// {
// int j=root;
// for(;*x;x++)
// {
// c=*x-'a';
// if(sum[c])
// }
// }
//}
//注释掉的是root任意值的情况,未完成,以下程序认为root为0号点
namespace AC
{
int ch[][],sum[],f[],mem,lst[];
void insert(char *x)
{
int now=,u;
for(;*x;x++)
{
u=*x-'a';
if(!ch[now][u]) ch[now][u]=++mem;
now=ch[now][u];
}
sum[now]++;
}
void build()
{
int c,t,u;
queue<int> q;
f[]=;
for(c=;c<;c++)
{
u=ch[][c];
if(u) {f[u]=;q.push(u);lst[u]=;}
}
while(!q.empty())
{
t=q.front();q.pop();
for(c=;c<;c++)
{
u=ch[t][c];
if(!u) {ch[t][c]=ch[f[t]][c];continue;}
q.push(u);
f[u]=ch[f[t]][c];
lst[u]=sum[f[u]]?f[u]:lst[f[u]];
}
}
}
int ans;
void get_ans(int j)
{
while(j)
{
ans+=sum[j];
sum[j]=;
j=lst[j];
}
}
int count(char *x)
{
ans=;
int j=,c;
for(;*x;x++)
{
c=*x-'a';
j=ch[j][c];
get_ans(j);
}
return ans;
}
}
int main()
{
int i;
scanf("%d",&n);
for(i=;i<=n;i++)
{
s[i]=sp;scanf("%s",s[i]);sp+=strlen(s[i])+;
AC::insert(s[i]);
}
AC::build();
scanf("%s",s2);
printf("%d",AC::count(s2));
return ;
}

P3796

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
#include<string>
using namespace std;
char *s[],tttt[],*sp,s2[];
int n;
namespace AC
{
int ch[][],sum[],f[],mem,lst[],ans[];
void clear()
{
int i,j;
for(i=;i<=mem;i++)
{
for(j=;j<;j++) ch[i][j]=;
sum[i]=f[i]=lst[i]=ans[i]=;
}
mem=;
}
int insert(char *x)
{
int now=,u;
for(;*x;x++)
{
u=*x-'a';
if(!ch[now][u]) ch[now][u]=++mem;
now=ch[now][u];
}
sum[now]++;
return now;
}
void build()
{
int c,t,u;
queue<int> q;
f[]=;
for(c=;c<;c++)
{
u=ch[][c];
if(u) {f[u]=;q.push(u);lst[u]=;}
}
while(!q.empty())
{
t=q.front();q.pop();
for(c=;c<;c++)
{
u=ch[t][c];
if(!u) {ch[t][c]=ch[f[t]][c];continue;}
q.push(u);
f[u]=ch[f[t]][c];
lst[u]=sum[f[u]]?f[u]:lst[f[u]];
}
}
}
void get_ans(int j)
{
while(j)
{
ans[j]+=sum[j];
j=lst[j];
}
}
void work(char *x)
{
int j=,c;
for(;*x;x++)
{
c=*x-'a';
j=ch[j][c];
get_ans(j);
}
}
}
int pos[];
int a1,anss;
int main()
{
int i;
while()
{
scanf("%d",&n);
if(n==) break;
AC::clear();
sp=tttt;
for(i=;i<=n;i++)
{
s[i]=sp;scanf("%s",s[i]);sp+=strlen(s[i])+;
pos[i]=AC::insert(s[i]);
}
AC::build();
scanf("%s",s2);
AC::work(s2);a1=anss=;
for(i=;i<=n;i++)
if(AC::ans[pos[i]]>a1)
a1=AC::ans[pos[i]];
for(i=;i<=n;i++)
if(AC::ans[pos[i]]==a1)
anss++;
printf("%d\n",a1);
for(i=;i<=n;i++)
if(AC::ans[pos[i]]==a1)
printf("%s\n",s[i]);
}
return ;
}

洛谷 P3808 【模板】AC自动机(简单版)洛谷 P3796 【模板】AC自动机(加强版)的更多相关文章

  1. [模板][P3808]AC自动机(简单版)

    Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...

  2. VueJS 获取并编译远程模板 解决方案(简单版)

    原文链接:https://savokiss.com/tech/vuejs-remote-template.html see: forum

  3. luogu P3808 【模板】AC自动机(简单版)

    题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...

  4. 洛谷P3808 & P3796 AC自动机模板

    题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...

  5. 模板】AC自动机(简单版)

    模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P3808 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保 ...

  6. 「LuoguP3808」 【模板】AC自动机(简单版)

    题目背景 通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. ...

  7. 【模板】AC自动机(简单版)

    我:“woc...AC自动机?” 我:“可以自动AC???” 然鹅... 大佬:“傻...” 我:“(⊙_⊙)?” 大佬:“缺...” 我:“......” (大佬...卒 | 逃...) emm.. ...

  8. AC自动机(简单版)(施工ing)

    声明 想看加强版的戳这里(施工ing,作者正努力中)~ 先贴题目吧哎~   AC自动机加强版  洛谷 P3796 题目: 洛谷 P3808 (数据范围困了我好久 TAT) 反正涉及字符串的算法都很玄学 ...

  9. 简单版AC自动机

    简单版\(AC\)自动机 学之前听别人说起一直以为很难,今天学了简单版的\(AC\)自动机,感觉海星,只要理解了\(KMP\)一切都好说. 前置知识:\(KMP\)(有链接) 前置知识:\(Trie\ ...

  10. luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)

    纪念一下我一晚上写了八遍AC自动机 这是加强版的: #include <iostream> #include <cstring> #include <cstdio> ...

随机推荐

  1. wikioi 2147 bitset+map解决

    题目描写叙述 Description 小明是一名天文爱好者,他喜欢晚上看星星.这天,他从淘宝上买下来了一个高级望远镜.他十分开心.于是他晚上去操场上看星星. 不同的星星发出不同的光,他的望远镜能够计算 ...

  2. Cubieboard搭建Hadoop指南

    1.刷固件 出厂的Cubieboard是Android系统,需要Linux系统安装Hadoop,到此网址下载: http://dl.cubieboard.org/software/a20-cubiet ...

  3. css中使input输入框与img(图片)在同一行居中对齐

    input,img{vertical-align:middle;},同时设置input和img的vertical-align属性,兼容ie7

  4. 【翻译自mos文章】oracle db 中的用户账户被锁--查看oracle用户的尝试次数

    參考原文: Users Accounts Getting Locked. (Doc ID 791037.1) 事实上这个文章是为oracle 别的软件产品写的,只是涉及到user 锁定问题.那还是跟d ...

  5. jsp_类的封装_集合的应用

    一.需求分析 做一个jsp页面,动态显示信息表的内容. 1.做一个实体类:StudentInfo(包含4个字段) 2.如图模拟生成3条数据,本质上就是new StudentInfo 3个实例, 每一个 ...

  6. A Simple Example About Privileged Methods in JavaScript

    Douglas Crockford classified the "class methods" in JavaScript into three types: private, ...

  7. [学习笔记]渗透测试metasploit

    1.渗透成功后,在meterpreter命令行,需要使用如下命令切换当前目录.更多信息,可以参考: meterpreter > pwd C:\ meterpreter > cd /&quo ...

  8. 密码过期导致Oracle process耗尽问题

    oracle忽然连不上! 大致是报这样的错: ORA-12516: TNS: 监听程序找不到符合协议堆栈要求的可用处理程序 ORA-12520: TNS: 监听程序无法为请求的服务器类型找到可用的处理 ...

  9. 不同linux版本下内核/系统/软件的安装及查询

    (一)先介绍下使用apt-get 和使用yum 包管理工具的不同用法: 1.先看yum(redhat) yum的配置文件是/etc/yum.conf 更新:yum update 安装:yum inst ...

  10. DBENV->open

    https://stuff.mit.edu/afs/sipb/project/sandbox/golem/db-3.0.55/docs/api_c/env_open.html #include < ...