#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<stack> using namespace std; #define Maxn 210 #define Maxm 1000010 struct n…
初学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]就等于它,否则就不停的跳fai…
STL 双向队列DEQUE版本 #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 50010 #define LL long long struct node…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 1010 #define INF 0xfffffff *Maxn],sum[*Maxn]; *Maxn][*M…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<stack> using namespace std; #define Maxn 1010 #define Maxm 1000010 ]; int…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<stack> using namespace std; #define Maxn 210 int match[Maxn]; int n,m; str…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<stack> using namespace std; #define Maxn 10010 #define Maxm 100010 struct…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 1000010 char s[Maxn]; int a[Maxn],nt[Maxn]; int l; void…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 110010 char s[Maxn]; int l; ],al,p[Maxn*]; int mymin(in…
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define Maxn 400010 char s[Maxn]; int l,nt[Maxn]; int mymin(int x,in…
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3493  Solved: 1909[Submit][Status][Discuss] Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽…
代码: //先把给的单词建AC自动机并且转移fail,然后d[i][j]表示构造的文章到第i位时处在字典树的第j个节点的不包含单词的数量,最后用总的数量26^m //-d[m][0~sz]即可.其中不能走单词结尾的节点以及他们的fail.这里其实要把每个节点都连向他的26个后继,但是不连也没关系可以看作 //那些没出现的节点都转移成了0节点. #include<iostream> #include<cstdio> #include<cstring> #include&l…
ac自动机中,如果以trie中的节点为节点,(fail[i],i)为边,可以建立一颗树,该树有如下特点:“节点u是节点v的祖先 当且仅当 u代表的字符串是v代表的字符串的一个后缀”.(u代表的字符串是由根节点到u路径上所有的边代表的字符顺次组合成的,我们记作str(u)). 本题中的每一个P都对应trie中的一个节点,所以本题就是求str(b)中有多少个str(a)子串: 如果len(str(b))<len(str(a)),则为0 如果len(str(b))==len(str(a)),则判断a和…
第一道AC自动机题目. 记一下对AC自动机的理解吧: AC自动机=Trie+KMP.即在Trie上应用KMP思想,实现多Pattern的匹配问题. 复杂度是预处理O(segma len(P)),匹配是O(len(T)).应该也是下界了. 它预处理做了以下事情: 1.建立所有Pattern的Trie 2.计算出fail和last数组 匹配时和KMP很像. 我对fail和last的理解: 对于一棵Trie,上面的一个节点对应一个字符串,该字符串是root到该节点的路径上,边代表的字符连接起来的. f…
比较容易看出来先建立ac自动机,然后在自动机上做DP,设w[0..1][i][j]为当前不包括/包括字典中的字符串,当前在自动机中走到第i个节点,完成的文本的长度为j的方案数,那么比较容易的转移w[i|j->child->cnt][j->child][k+1]+=w[i][j][k]. /**************************************************************     Problem: 1030     User: BLADEVIL  …
思路:我们先跟着它给定的字符串走把字典树建出来,求出fail指针,我们考虑两个字符串 A和B, 如果想要求B中有多少A的子串,转换一下就是有多少个B的前缀的后缀包含A,这个在AC自动机 的状态图中很容易表示,就是字符串B所占的结点中 有多少个结点顺着fail能到达A的尾结点, 并且fail构建出来的图是一棵树,转换成A的尾结点的子树中有多少个B的节点,用dfs序构建树状 数组能很容易完成,又因为有m组询问,我们把询问离线排序,就能解决问题啦. #include<bits/stdc++.h> #…
恶补了一下AC自动机,花了一天时间终于全部搞明白了. 思路:将每个人的串加入AC自动机,在AC自动机生成的状态图上建边,注意单词末尾的节点只能转移到自己概率为1, 然后将矩阵自乘几十次后误差就很小了, 或者可以高斯消元搞出精确解. #include<bits/stdc++.h> #define LL long long #define ll long long #define fi first #define se second #define mk make_pair #define pii…
思路: 需要维护一个栈的AC自动机--. 要求出来 最后的栈顶是在自动机上的哪个节点. if(!ac.ch[st[tp-1]][a[i]-'a']) st[tp]=ac.ch[ac.f[st[tp-1]]][a[i]-'a']; else st[tp]=ac.ch[st[tp-1]][a[i]-'a']; 如果ch[][] 到不了根 就要走到fail //By SiriusRen #include <queue> #include <cstdio> #include <cst…
思路: 我们先对所有读进来的T建一个AC自动机 因为走到一个禁忌串就需要回到根 所以呢 搞出来所有的结束点 或一下 fail指针指向的那个点 然后我们就想转移 a[i][j]表示从i节点转移到j节点的概率 如果能够转移到 ans+=1÷alphabet 这里有一个trick 建一个size+1节点 如果回到了根 就连到size+1 a[size+1][size+1]=1 这样就成了累加和了 因为长度最大有10^9,显然直接DP会无论空间还是时间都会爆炸... 所以用矩阵乘法+快速幂加速转移 现在…
又打了一遍AC自动稽. 海星. 好像是第一次打trie图,很久以前就听闻这个思想了.OrzYYB~ // It is made by XZZ #include<cstdio> #include<algorithm> #include<cstring> #define il inline #define rg register #define vd void #define sta static typedef long long ll; il int gi(){ rg…
思路:直接在状态图上跑dp,最后枚举一下42种一下的.. 这个枚举有点恶心. #include<bits/stdc++.h> #define LL long long #define ll long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using n…
思路:将能跑到的状态标记一下,在bfs搜一下就好啦. #include<bits/stdc++.h> #define LL long long #define ll long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std…
#include<bits/stdc++.h> #define LL long long #define ll long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; + ; ; const int inf = 0x3…
根据题意建出trie图,代表单词的点不能走,直接或间接指向它的点也不能走.这样的话如果能在图中找到一个环的话就是TAK,否则是NIE. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define N 30005 using namespace std; int n;bool flag; ]; ]; char s[…
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意 题目描述 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. 输入输出格式 输入格式: 第一行一个n,表示模式串个数: 下面n行每行一个模式串: 下面一行一个文本串. 输出格式: 一个数表示答案 输入输出样例 输入样例#1: 2 a aa aa 输出样例#1: 2 说明 su…
AC自动机(Aho-Corasick Automata)是经典的多模式匹配算法.从前我学过这个算法,但理解的不深刻,现在已经十分不明了了.现在发觉自己对大部分算法的掌握都有问题,决定重写一系列博客把学过的算法review一下,目标是: 充分理解算法的原理与实现细节 形成一个简洁明了,能很好反映原理的写法,作为模板 Codeforces上讲解AC自动机的一篇博客. Wikipedia  词条Aho–Corasick algorithm Overview Concepts finite state…
将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cstdio> #include <cstring> #include <queue> using namespace std; ; ; ]; struct AhoCorasickAutomata { int ch[maxnode][sigma_size]; int match[ma…
我这个蒟蒻第一次写博客,有点小激动呢. 主要是最近刚学了AC自动机,学得糟糟糕糕,记录一下,看到dalao们都在写博客,决定自己也写一波[我好水的啦,写的也不好] AC自动机大概就是    Trie+KMP=AC自动机 嗯,在KMP中,引入了字符串失配最优转移方案:失配函数f[i],在j位匹配失败后,便转到f[j]位匹配 同样的道理,AC自动机就是升维的KMP,在匹配时不仅要考虑当前模板串,还要顾及其它模板串,所以失配函数还要顾及其它模板串,匹配成功也要考虑其它模板串 所以,AC自动机采用了bf…
Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为 0 Input 第一行输入N,M,K.接下来一行输入M位的数. N<=10^9,M<=20,K<=1000 Output 阿申想知道不出现不吉利数字的号码有多少种,输出模K取余…
AC自动机 UVa 11468 题意:给一些字符和各自出现的概率,在其中随机选择L次,形成长度为L的字符串S,给定K个模板串,求S不包含任意一个串的概率. 首先介绍改良版的AC自动机: 传统的AC自动机,是当一个字符失配时,根据失配函数转移到指定地方,而这个失配函数,是通过一个宽搜的过程形成的,这时在匹配串的时候,就当匹配失败时,顺着失配指针走,直到可以匹配.然后匹配到单词结点,或者后缀链接是一个单词结点,这些前面的结点也是匹配单词.这就是传统的AC自动机. 现在将这个AC自动机改版优化: 具体…