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 ...
随机推荐
- iOS UIControl 详解
UIControl是UIView的子类,当然也是UIResponder的子类.UIControl是诸如UIButton,UISwitch,UItextField等控件的父类,它本身包含了一些属性和方法 ...
- http协议(四)http状态码
一:http状态码 表示客户端http请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作 状态码的类别如下: http状态码种类繁多,大概有60多种,实际上经常使用的只有14种,下面为一 ...
- 根据Unicode编码用C#语言把它转换成汉字的代码
rt 根据所具有的Unicode编码用C#语言把它转换成汉字的代码 var s = System.Web.HttpUtility.HtmlDecode(Utf8Str); var o = Newton ...
- 折腾了1周把程序从sqlserver迁移到oracle上了,每折腾一次需要耗费1周时间
主要花费时间的事情: 1:安装配套的服务器,安装操作系统,安装数据库,配置远程访问等等,一般会耗费1天时间,甚至2天时间,若手头安装盘不齐全,需要耗费更多时间. 2:远程传输安装文件.特别是开发环境等 ...
- Android性能优化之Systrace工具介绍(一) _&& Systrace生成的trace.html打开空白或者打不开的解决办法
1.必须用Chrome打开 2.在mac电脑上,可能Chrome打开也是空白,解决办法是:在chrome地址栏中输入”chrome:tracing”,然后点击load按钮load你的trace.htm ...
- gradient 线性渐变 浏览器兼容
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=white, endColorstr= ...
- CentOs下jdk的安装
jdk的安装是咱搞java的基本功了,在window上配置了没上百次也有几十次了,今天换个环境,需要在linux系统上安装,而服务器版本的CentOs是纯命令行的, 因此也给配置jdk增加了不少难度, ...
- Qt学习笔记 QMessageBox
Qt的几种MessageBox 1.Infomation类型 QMessageBox::information(this,tr("hello"),tr("title&qu ...
- 两个Canvas小游戏
或许连小游戏都算不上,可以叫做mini游戏. 没有任何框架或者稍微有点深度的东西,所以有js基础的或者要追求炫酷效果的可以直接ctrl+w了. 先贴出两个游戏的试玩地址: 是男人就走30步 是男人就忍 ...
- 为 Xamarin.Forms 做个跑马灯控件
前段时间,私下用 Xamarin.Forms 做了个商业项目的演示版.很多被国内App玩坏了的控件/效果,XF上都没有或是找不到对应的实现,没有办法只能亲自上阵写了几个,效果还行,就是有BUG. 这个 ...