bzoj 3172 AC自动机
初学AC自动机,要先对于每一个模式串求出来trie树,在此基础上构建fail指针,然后在trie树加上失配边构建出整张trie图。
AC自动机的原理和KMP差不多,一个节点的fail指针就是指向trie树上一个最长前缀等于这个单词的后缀。
首先fail[0]=0,然后把0有的每个孩子push进一个队列里(如果直接push(0)的话会出现f[x]=x),然后bfs。
设一个节点为u,父亲为v,那么如果ch[fail[v]][u是v的哪个孩子]!=0,那么fail[u]就等于它,否则就不停的跳fail直到0或存在这个孩子。
但我们可以用trie图来优化这个过程,每个节点的每个孩子都不为空,如果原本为空就直接指向上一步用while循环求的那个孩子(具体看代码),于是跳的时候无脑跳一步就行了。
考虑这道题,一个单词一定为trie上的一个节点,而且它出现在文章中一定是一个前缀的后缀,所以那些fail指针直接或间接指向它的节点一定包含这个前缀,所以用bfs序倒着dp一遍就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 1000005
using namespace std;
int n;
char s[N];
int cnt;
int ch[N][],f[N],ans[N],sum[N];
int b[N];
void in(int xx)
{
int now=,l=strlen(s);
for(int i=;i<l;i++)
{
int x=s[i]-'a';
if(!ch[now][x])ch[now][x]=++cnt;
now=ch[now][x];sum[now]++;
}
b[xx]=now;
}
queue<int>q;int a[N];int tot;
void fail()
{
f[]=;
for(int i=;i<;i++)
{
int u=ch[][i];
if(u)q.push(u),a[++tot]=u;
}
while(!q.empty())
{
int tmp=q.front();q.pop();a[++tot]=tmp;
for(int i=;i<;i++)
{
int u=ch[tmp][i];
if(!u)
{
ch[tmp][i]=ch[f[tmp]][i];continue;
}
q.push(u);f[u]=ch[f[tmp]][i];
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s);
in(i);
}
fail();
for(int i=tot;i>=;i--)sum[f[a[i]]]+=sum[a[i]];
for(int i=;i<=n;i++)
{
printf("%d\n",sum[b[i]]);
}
return ;
}
bzoj 3172 AC自动机的更多相关文章
- 【无聊放个模板系列】BZOJ 3172 (AC自动机)
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...
- bzoj 2434 AC自动机+树状数组
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3493 Solved: 1909[Submit][Sta ...
- bzoj 1030 AC自动机+dp
代码: //先把给的单词建AC自动机并且转移fail,然后d[i][j]表示构造的文章到第i位时处在字典树的第j个节点的不包含单词的数量,最后用总的数量26^m //-d[m][0~sz]即可.其中不 ...
- bzoj 2434 ac自动机
ac自动机中,如果以trie中的节点为节点,(fail[i],i)为边,可以建立一颗树,该树有如下特点:“节点u是节点v的祖先 当且仅当 u代表的字符串是v代表的字符串的一个后缀”.(u代表的字符串是 ...
- bzoj 2754 ac自动机
第一道AC自动机题目. 记一下对AC自动机的理解吧: AC自动机=Trie+KMP.即在Trie上应用KMP思想,实现多Pattern的匹配问题. 复杂度是预处理O(segma len(P)),匹配是 ...
- bzoj 1030 ac自动机
比较容易看出来先建立ac自动机,然后在自动机上做DP,设w[0..1][i][j]为当前不包括/包括字典中的字符串,当前在自动机中走到第i个节点,完成的文本的长度为j的方案数,那么比较容易的转移w[i ...
- bzoj 2434 AC自动机 + fail指针建树 + 树状数组
思路:我们先跟着它给定的字符串走把字典树建出来,求出fail指针,我们考虑两个字符串 A和B, 如果想要求B中有多少A的子串,转换一下就是有多少个B的前缀的后缀包含A,这个在AC自动机 的状态图中很容 ...
- bzoj 1444 AC自动机 + 矩阵乘法 | 高斯消元
恶补了一下AC自动机,花了一天时间终于全部搞明白了. 思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1, 然后将矩阵自乘几十次后误差就很小了, ...
- BZOJ 3940 AC自动机
思路: 需要维护一个栈的AC自动机--. 要求出来 最后的栈顶是在自动机上的哪个节点. if(!ac.ch[st[tp-1]][a[i]-'a']) st[tp]=ac.ch[ac.f[st[tp-1 ...
随机推荐
- JQuery常用方法(均实践过)
1,使用jquery修改html元素的值 a,修改form的action的值(即修改html的属性值) 这个可以扩展为修改html元素的属性值的方法,使用的$("#id").att ...
- page-cache层
pagecache层内存管理 如果使用page,尤其对于32位系统来说,kmap & kunmap,可以把做struct *page与虚拟地址的映射 用kmap做一个临时的映射,然后通过kun ...
- xhEditor用法
xhEditor是一个基于jQuery开发的简单迷你并且高效的在线可视化HTML编辑器,而且兼容很多浏览器,所以就选它了,具体使用如下: 1 .下载xhEditor 最新版本 下载地址:http:// ...
- html之marquee详解
该标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可能无法看到下面一些很有意思的效果该标签是个容器标签语法: <marquee ...
- swift 随机生成背景颜色
swift是一门新语言,相关的文档资料现在基本上还不是很完整.在尝试开发过程中,走了不少弯路.在这里记录一下自己的”路“,希望以后能少走弯路. 生成随机背景颜色使用的语法和C#或者JAVA基本一致. ...
- 利用performance属性查看网页性能
一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获得更为精确的原始数据,以毫秒为单位,精确到微秒. pe ...
- 项目分享一:在项目中使用 IScroll 所碰到的那些坑
最近做了个 WEB APP 项目,用到了大名鼎鼎的 IScroll,滚动的效果的确很赞,但是坑也是特别多,下面总结一下,希望自后来者有帮助. 该项目现已开源在 github 上,https://git ...
- 踩到一个Emit的坑,留个纪念
重现代码: var dmFoo = new DynamicMethod("Foo", typeof(void), Type.EmptyTypes); var ilFoo = dmF ...
- JavaScript学习笔记-简单的计时钟表
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- 东大OJ-1040-Count-快速幂方法求解斐波那契-
Many ACM team name may be very funny,such as "Complier_Error","VVVVV".Oh,wait fo ...