洛谷 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> ...
随机推荐
- Meteor部
一个关于 Meteor 主要事项就是如何轻松部署应用程序.当程序完成后,有一个简单的方法来和世界分享你的应用程序.所有需要做的就是在运行命令提示符窗口下面的代码. C:\Users\Administr ...
- Dell R420 RAID建立以及系统安装
http://thefallenheaven.blog.51cto.com/450907/1753472 Dell R420的RAID划分,以及系统安装 3块2T的盘,装好硬盘后开机,这里有3种方式去 ...
- MapReduce输入输出类型、格式及实例
输入格式 1.输入分片与记录 2.文件输入 3.文本输入 4.二进制输入 5.多文件输入 6.数据库格式输入 1.输入分片与记录 1.JobClient通过指定的输入文件的格式来生成数据分片Input ...
- webpack-Hot Module Replacement(热更新)
模块热替换(Hot Module Replacement) 模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面 ...
- getifaddrs
getifaddrs 获取本地网络接口的信息.在路由器上可以用这个接口来获取wan/lan等接口当前的ip地址,广播地址等信息. #include <sys/types.h> #inclu ...
- BestCoder #49 Untitled HDU 5339
BestCoder #49 Untitled HDU 5339 题目: http://acm.hdu.edu.cn/showproblem.php? pid=5339 本题採用深搜, 数据量小,先做 ...
- sshclientCRT连接linux使用技巧
设置仿真和回滚缓冲区 字体外观设置 日志文件设置 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fi ...
- Fluently NHibernate 插入CLOB字段
ORA-01461: can bind a LONG value only for insert into a LONG column 插入oracle某表时报的错. 查来查去,是插入的某个字段值超长 ...
- Latex 3: 解决LaTeX编译卡顿问题
1.问题: 最近在编译latex时,老是在tulmr.fd处编译很久,但是以前不这样啊,那肯定就是我最近做了什么导致这样的了,是什么呢? 2.解决: 后来google下发现了解决办法,原来是我新安装了 ...
- SAP 常用增强记录文档
转自:http://blog.csdn.net/budaha 20170215需要一个PR 修改保存时候的增强,目的是同步PR的处理状态 EBAN-STATU 到一个自建表ZTPRTOPO,记得有个P ...