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. Python pandas学习笔记

    参考文献:<Python金融大数据分析> #导入模块 import pandas as pd #生成dataframe df = pd.DataFrame([10,20,30,40], c ...

  2. DLL混淆

  3. Android调试工具_ Stetho

    Stetho是Facebook开源的一个Android平台调试工具. Stetho能实如今不root手机的情况下,通过Chrome查看App的布局,Sqlite,SharedPreference.Ne ...

  4. Node.js - 断言

    什么是断言? 程序中的断言是什么意思,让我们带着疑问一步步探索 断言即我们相信程序某个特定点布尔表达式为真 举个例子就是: 我相信你是对的,然后让别人判断一下你是对的或错的,最后我得到结果. 好了,进 ...

  5. vue :src 文件路径错误

    首先先说明下vue-cli的assets和static的两个文件的区别,因为这对你理解后面的解决办法会有所帮助 assets:在项目编译的过程中会被webpack处理解析为模块依赖,只支持相对路径的形 ...

  6. OSChinaclient源代码学习(2)--缓存的设计

    一.缓存的作用 请求数据的时候,首先进行推断,能否够从缓存中获取数据,假设满足条件,则直接从缓存中获取数据.否则请求新的数据.这样比没有缓存的情况下.每次都要从server请求数据要快,并且.没有网的 ...

  7. Codeforces 104C Cthulhu dfs暴力 || 点双连通缩点

    题目链接:点击打开链接 题意: 给定n个点m条边的无向图 问图中是否存在 有且仅有一个简单环和一些树,且这些树的root都在这个简单环上. 瞎写了个点双. . == #include <stdi ...

  8. hdu4737A Bit Fun 线段树

    //给一串序列,问有多少对[i,j]使得 //[i,j]区间的全部数的或的值小于m //能够知道'或'操作的加(a|b)>=max(a,b) //能够枚举区间的右边r,找左边第一个不满足的位置 ...

  9. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM(转载)

    http://www.cnblogs.com/indream/p/3602348.html 刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code ...

  10. apply current folder view to all folders

    https://www.tenforums.com/tutorials/35093-apply-folder-view-all-folders-same-type-windows-10-a.html ...