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. Fragment实践之聊天窗体

    前几天刚学了android的fragment,总是停留在简单的demo,也许永远都学不会. 今天,我要动手向我的聊天软件开刀.今天.用Fragment来实现一个例如以下图效果的聊天界面. waterm ...

  2. 如何在 Linux 环境下配置 Nagios Remote Plugin Executor (NRPE)

    为 NRPE 配置自定义命令 远程服务器上安装 下面列出了一些可以用于 NRPE 的自定义命令.这些命令在远程服务器的 /etc/nagios/nrpe.cfg 文件中定义. ## 当 1.5.15 ...

  3. [Rust] Setup Rust for WebAssembly

    In order to setup a project we need to install the nightly build of Rust and add the WebAssembly tar ...

  4. [TypeScript] Query Properties with keyof and Lookup Types in TypeScript

    The keyof operator produces a union type of all known, public property names of a given type. You ca ...

  5. [Hibernate Search] (3) 基础查询

    基础查询 眼下我们仅仅用到了基于keyword的查询,实际上Hibenrate Search DSL还提供了其他的查询方式,以下我们就来一探到底. 映射API和查询API 对于映射API.我们能够通过 ...

  6. C# 性能优化 之 秒表 Stopwatch。 Dapper一个和petapoco差不多的轻量级ORM框架

    Sweet小马 小马同学的编程日记. C# 性能优化 之 秒表 Stopwatch. 生词解释:Diagnostics[,daɪəg'nɑstɪks] n.诊断学 using System.Diagn ...

  7. bootstrap中固定table的表头

    前端时间鼓捣的一个简单的手机站点,今天又拿出来弄一弄 由于主要是给手机訪问.用的是bootstrap响应式布局,今天的任务是做一个数据展示页面 可是因为数据的列比較多.所以横向显示不下,为了较好的显示 ...

  8. 纯JS写的一款记录事项的单页应用

    要点: 1.使用localStorage存储 2._change_record_progress函数以字符串作为参数,用eval执行这个参数 3.使用了jQuery自定义事件,便于数据改变时实时更新显 ...

  9. QuickFont使用中的3D物体消失问题

    使用基于OpenTK的QuickFont显示字体的时候,会遇到绘制的3D物体消失的问题. 搜索OpenTK的论坛后,解决办法如下: 在执行QFont.End()语句后,再后面添加GL.Disable( ...

  10. 嵌入式开发之davinci--- 8148/8168/8127 中的图像缩放sclr、swms之后出现图像视频卡顿、屏幕跳跃的问题

    ()问题原因 这边的case链路是这样的camera->sclr(yuv420sp cif)->dup->ipcframeoutm3<->ipcframerocess&l ...