洛谷 P3808 【模板】AC自动机(简单版)洛谷 P3796 【模板】AC自动机(加强版)
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自动机(加强版)的更多相关文章
- [模板][P3808]AC自动机(简单版)
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...
- VueJS 获取并编译远程模板 解决方案(简单版)
原文链接:https://savokiss.com/tech/vuejs-remote-template.html see: forum
- luogu P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- 洛谷P3808 & P3796 AC自动机模板
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...
- 模板】AC自动机(简单版)
模板]AC自动机(简单版) https://www.luogu.org/problemnew/show/P3808 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保 ...
- 「LuoguP3808」 【模板】AC自动机(简单版)
题目背景 通过套取数据而直接“打表”过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. ...
- 【模板】AC自动机(简单版)
我:“woc...AC自动机?” 我:“可以自动AC???” 然鹅... 大佬:“傻...” 我:“(⊙_⊙)?” 大佬:“缺...” 我:“......” (大佬...卒 | 逃...) emm.. ...
- AC自动机(简单版)(施工ing)
声明 想看加强版的戳这里(施工ing,作者正努力中)~ 先贴题目吧哎~ AC自动机加强版 洛谷 P3796 题目: 洛谷 P3808 (数据范围困了我好久 TAT) 反正涉及字符串的算法都很玄学 ...
- 简单版AC自动机
简单版\(AC\)自动机 学之前听别人说起一直以为很难,今天学了简单版的\(AC\)自动机,感觉海星,只要理解了\(KMP\)一切都好说. 前置知识:\(KMP\)(有链接) 前置知识:\(Trie\ ...
- luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)
纪念一下我一晚上写了八遍AC自动机 这是加强版的: #include <iostream> #include <cstring> #include <cstdio> ...
随机推荐
- 【转】c++ 如何批量初始化数组 fill和fill_n函数的应用
http://blog.csdn.net/sunquana/article/details/9153213 一. fill和fill_n函数的应用: fill函数的作用是:将一个区间的元素都赋予val ...
- JAVA学习(一):Java介绍及其平台、开发环境的配置与搭建
Java介绍及其平台.开发环境的配置与搭建 1.Java的介绍 Java是一种面向对象的编程语言,具有跨平台.可移植.分布式.简单.可扩展等诸多特性.Java能够进行桌面应用.Web应用.分布式系统及 ...
- coco2d-x怎样创建project
不知道coco2d-x从那个版本号開始用python创建project,一句话搞定,确实省去了好多麻烦. 首先定位到coco2d-x的文件夹到cocos2d-x-2.2.3\cocos2d-x-2.2 ...
- HBase单机环境搭建
在搭建HBase单机环境之前,首先你要保证你已经搭建好Java环境: $ java -version java version "1.8.0_51" Java(TM) SE Run ...
- strtok函数
strtok函数是cstring文件里的函数 strtok函数是cstring文件里的函数 其功能是截断字符串 原型为:char *strtok(char s[],const char *delin) ...
- Android开发之自己定义Spinner样式的效果实现(源码实现)
android系统自带的Spinner样式是远远满足不了我们实际开发过程中对Spinner UI风格的要求,因此我们肯定须要为了切合整个应用的风格,改动我们的Spinner样式.系统给我们提供了两种常 ...
- udhcp详解源码(序)
最近负责接入模块,包括dhcp.ipoe和pppoe等等.所以需要对dhcp和ppp这几个app的源代码进行一些分析.网上有比较好的文章,参考并补充自己的分析. 这篇udhcp详解是基于busybox ...
- 4 自动化构建工具gulp
gulp中文网:http://www.gulpjs.com.cn/ 需要全局安装gulp:$ npm install --global gulp 具体的gulp的使用方法,可以参看gulp中文网的文档 ...
- 【IOS】启动画面
总述: 两种方式,一种是使用系统自带的.按规则定义启动图片名称就可以,显示为1秒,要想延长时间,用[nsthread sleepForTimeInterval:5.0] ,还有一种就是自己定义ui ...
- SSH三大框架整合配置详细步骤(3)
5 配置Spring2.5 5.1 基础配置 1) 导入spring包.下载spring-framework-2.5.6并解压后,在spring-framework-2.5.6" ...