UVA 11468 AC 自动机】的更多相关文章

AC自动机 UVa 11468 题意:给一些字符和各自出现的概率,在其中随机选择L次,形成长度为L的字符串S,给定K个模板串,求S不包含任意一个串的概率. 首先介绍改良版的AC自动机: 传统的AC自动机,是当一个字符失配时,根据失配函数转移到指定地方,而这个失配函数,是通过一个宽搜的过程形成的,这时在匹配串的时候,就当匹配失败时,顺着失配指针走,直到可以匹配.然后匹配到单词结点,或者后缀链接是一个单词结点,这些前面的结点也是匹配单词.这就是传统的AC自动机. 现在将这个AC自动机改版优化: 具体…
将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cstdio> #include <cstring> #include <queue> using namespace std; ; ; ]; struct AhoCorasickAutomata { int ch[maxnode][sigma_size]; int match[ma…
建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG的数据: 这组数据我觉得答案应该是1吧,无论如何组合'a'和'b'这两个字符,也无法得到模式串"ac"和"bd"!! AC代码 #include <stdio.h> #include <string.h> #include <queue&g…
题意: 给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S. 给出K个模板串,计算S不包含任何一个模板串的概率 dp[i][j]表示走到AC自动机 i 这个节点 还需要走 j 步的概率. 表示不会概率DP ,看网上题解写的. 通过记忆化搜索去写. 注意一点字符有大小字母和数字 #include <set> #include <map> #include <stack> #include <queue> #include <c…
首先我们应该是枚举 L个位置上的每个字符来得到最终概率 然后AC自动机的作用就是为了判断你枚举的地方是否对应了单词节点,如果对应了,就肯定要不得 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; ; ; ; int idx[N],k,n; ][]; ]; //这个地方…
/** 链接:https://vjudge.net/problem/UVA-11468 详见lrj训练指南P218 我的是反向求存在模板串的概率. dp[i][j]表示当前i位置选择字符,前面i-1个字符在自动机的匹配节点编号为j时候的状态可以获得的存在概率. 书上的好简洁,求idx(c)直接利用已经给定的n个字符的下标作为结果. 正向求解!厉害. */ #include<bits/stdc++.h> using namespace std; #define P pair<int,int…
#include<cstdio> #include<cstring> #include<queue> #include<cstdio> #include<map> #include<string> using namespace std; ; ; // 结点总数 + ; // 模板个数 ], n; double prob[SIGMA_SIZE]; struct AhoCorasickAutomata { int ch[MAXNODE]…
就向书上说得那样,如果模式串P的第i行出现在文本串T的第r行第c列,则cnt[r-i][c]++; 还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次出现的位置.如果repr[i] == i,说明这个模式串之前没有重复过,可以加进自动机里去.有重复的话,把这些重复的模式串组织成一个链表,用next把它们连接起来. 所以在统计cnt的时候,匹配到的模式串可能会作为匹配的第i行,也可能是next[i]行,next[next[i]]行等等. #incl…
题目链接:http://vjudge.net/contest/142513#problem/A 题意:给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L的随机字符串S.给出K个模版串,计算S不包含任何一个串的概率. 分析: 在构造好的AC自动机里面,每随机生成一个字母,相当于在AC自动机中随机走一步.所有单词结点标记为禁止,本题就是从结点 0 走 l 步,不进入任何禁止结点的概率. #include <bits/stdc++.h> using namespace std; ;…
图片加载可能有点慢,请跳过题面先看题解,谢谢 这个鬼题目,上一波套路好了 先用题目给的模板串建\(AC\)自动机,把单词结尾标记为 \(val=1\),然后在建好的\(AC\)自动机上跑 \(dp\), 设 \(f[x][L]\) 为:当前在 \(x\) 节点,剩下还要走 \(L\) 步并且不经过单词结尾的概率 那么有转移: \(f[x][L]=\sum_{!val[son[x][i]]}p[i]*dp(son[x][i],L-1)\),可以记忆搜实现 $ $ //made by Hero_of…