传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; void read(int &x) { char ch; bool ok; for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar(…
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有70pts 然后思考一下,正解怎么做呢QAQ 回到AC自动机中关于fail指针的定义上来,因为fail指针指向的是最长后缀,这意味着,假如a指向b,那么a字符串中一定包含有root到b这一段字符串 于是假如我们要统计的字符串x,就只需要统计有多少个fail指针直接或间接指向x的ed那个点就是as辣 那…
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后). l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失. l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失. 我们把纸上打印出来的字符串从1开始顺序编号,一直到n.打字机有一个非…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1277 推荐一篇博客(看思路就可以,实现用的是java): https://www.cnblogs.com/nullzx/p/7499397.html 这是一道模板题,拿来练手,之前看了一篇博客,有点错误,但是hdu上面居然过了,最主要的是我在hdu上面三道AC自动机模板题都是这个错的代码,居然都过了,害的我纠结了一晚上,原来是数据太水了. 主要还是看上面的博客,写了点注释,不一定对,以后好拿来复习.…
模板 :  #include<string.h> #include<stdio.h> #include<malloc.h> #include<iostream> #include<algorithm> using namespace std; ; struct Trie { Trie *Next[maxn]; int v; inline void init(){ ; ; i<maxn; i++) this->Next[i] = NUL…
Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4140  Solved: 2276[Submit][Status][Discuss] Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的:l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后).l 按一下印有'B'的按键,打字机凹槽…
题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能等于 \(v\))和一个非空字符串 \(s\) ,问从 \(u\) 到 \(v\) 的简单路径上的所有边按照到 \(u\) 的距离从小到大的顺序排列后,询问边上的字符依次拼接形成的字符串中给定的串 \(s\) 出现了多少次. 输入 第一行 \(2\) 个整数,依次为树中点的个数 \(n\) 和回忆的…
题面传送门 好久每做过 AC 自动机的题了--做几个题回忆一下罢 AC 自动机能够解决多串匹配问题,注意是匹配,碰到前后缀的问题那多半不在 AC 自动机能解决的范围内. 在初学 AC 自动机的时候相信大家都做过一道题叫做 P2414 [NOI2011] 阿狸的打字机.在这道题中我们用到了两棵树,一棵就是所有串的字典树,称为 trie 树,令一棵是求出每个点的 \(fail_i\) 后,对于所有不是根节点的 \(i\) 连边 \((fail_i,i)\) 后形成的树,称为 fail 树. 在那道题…
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的子串,那么就中奖了,否则不中.Bob会告诉你这M个序列,和身上有的钱的总数N,当然还有R的范围.请你告诉Bob中奖的概率有多少? 输入格式 第一行三个用空格隔开的数N.M和R的范围R.其中1<=R<=9,0<N<=60,0<M<=20000.下面M行每行一个字符串(长度小于…
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法.AC自动机详解.考虑到有时候字典会相当稀疏,所以引入了chi和bro指针进行优化——其原理比较类似于邻接表,这个东西和next数组本质上是一致的,只是chi和bro用于遍历某一节点下的子节点,next用于查询某节点下是否有需要的子节点) type point=^node; node=record ex:longint;st…
题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. “2 x”,Alice询问Bob,集合T中有多少个字符串包含串S_x.(我们称串A包含串B,当且仅当B是A的子串) Bob遇到了困难,需要你的帮助. 输入 第1行,一个数n: 接下来n行,每行一个字符串表示S_i: 下一行,一个数q: 接下来q行,每行一个操作,格式见题目描述. 输出 对于每一个Al…
题意 给定 \(n\) 个单词,\(q\) 个询问,每个询问包含两个串 \(s_1,s_2\),询问有多少个单词以 \(s_1\) 为前缀, \(s_2\) 为后缀,前后缀不能重叠. \(1 \leq n,q \leq 10^5\) 思路 字符串题有一个小技巧,拼接字符串,中间加上连接符.如这道题,可以将查询变成 \(s_2+\text{\{}+s_1\) 的形式,相应的,把单词 \(T\) 变为 \(T+\text{\{}+T\) 的形式.那么就是普通的匹配问题了. 对于询问建立\(\text…
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3493  Solved: 1909[Submit][Status][Discuss] Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽…
[NOI2011] 阿狸的打字机 题目描述: 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后). ·按一下印有'B'的按键,打字机凹槽中最后一个字母会消失. ·按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失. 例如,阿狸输入aPaPBbP,纸上被…
[题目大意] 输入一个字符串,其中:(1)a..z:在字符串末尾添加当前字符(2)P:输出当前字符串(3)B:从当前字符串末尾删去一个字符. 给出m组查询,输出第i个输出的字符串在第j个输出的字符串内出现了几次. [思路] 卡了好久,写完不想调试,调试完不想提交,期间颓颓颓地弄了下博客的界面,弄成了粉嫩少女风(划掉).结果提交完1A有点迷醉迷醉的…… 首先我们要借用BZOJ3172的结论:★←戳这里,这个结论66666,是本次解题的关键. “建立AC自动机,对于路径上的每一个点sum++,表示出…
传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; void read(int &x) { char ch; bool ok; for(ok=0,ch=getchar()…
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题目中这种多个串匹配的问题,一下子就想到了AC自动机.然后发现如果要建立AC自动机,跟着题目中的方式,不用把每个串提出来.如果是一个普通字符就直接加进去,如果是P就把当前节点记录下来,代表一个串,如果是B就相当于退回到trie树中的父亲节点. 建好AC自动机后来观察一下题目中的问题.这个询问相当于统计从根节点到代表y串的那个节点上的路径上,有多少个节点可以通过跳fail指针的方式到…
SAM+线段树合并的裸题. 但我们讨论AC自动机的做法. 先建出AC自动机.考虑询问在[a,b]中出现的次数就是\([1,b]\)的出现次数-\([1,a-1]\)的出现次数.把询问离线.然后我们要求的就是第i个字符串在\([1,x]\)中出现次数.我们在从\([1,x-1]\)到\([1,x]\)的过程中把\(S_x\)放到AC自动机上跑,跑到的每一个节点都加1.然后询问就是在\(S_i\)在fail树上对应位置求一个子树和这个用树状数组维护就行.因为fail树上每一个节点的后代都包含这个节点…
建立AC自动机然后,加入一个串之后考虑这个串的贡献.我们把这个串扔到AC自动机里面跑.最后对经过每一个点到的这个点在fail树的根的路径上的点有1的贡献.求链的并,我们把这些点按DFS序排序,然后把每一个点加1,每个点与上一个点的LCA-1,然后询问时的答案就是子树和这个用树状数组维护就行.至于为什么这么做最好自己动手画一画. #include<iostream> #include<cstring> #include<cstdio> #include<cmath&…
AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思义,就是当匹配失败的时候,用于引导p指针回溯,就和KMP算法中的next数组道理相同. #include<bits/stdc++.h> using namespace std; #define MAX 26 //字典树关键字为‘a’~‘b’ ]; //主串(文章) int n; //模式串共有n串…
题意: 就是现在给出m个串,每个串都有一个权值,现在你要找到一个长度不超过n的字符串, 其中之前的m个串每出现一次就算一次那个字符串的权值, 求能找到的最大权值的字符串,如果存在多个解,输出最短的字典序最小的串. 当最大全权值为0时输出空串. 输入最多100个子串,权值为不超过100的正整数. 每个子串长度至少为1,不超过10, n <= 50 如果不考虑方案输出,这题就变得相当简单了. dp[i][j]表示走到长度为 i 的时候 ,到AC自动机 j 这个节点所获得的最大权值和. 我一开始的做法…
题面传送门 第一眼看成了 CF547E-- 话说 CF587F 和 CF547E 出题人一样欸--还有另一道 AC 自动机的题 CF696D 也是这位名叫 PrinceOfPersia 的出题人出的--似乎这位神仙很擅长字符串? 跑题了跑题了-- 令 \(m=\sum|s_i|\) u1s1 我做这题的时候一直在考虑按照 CF547E 的套路对询问进行差分处理,然鹅并没有什么卵用.因为这题相当于每次加入一个字符串时将这个字符串结尾位置 fail 树的子树中的所有节点访问次数 \(+1\),并询问…
题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一行为一个正整数$N$ ,表示共有$N$ 个模式串,$1 \leq N \leq 150$ . 接下去$N$ 行,每行一个长度小于等于$70$ 的模式串.下一行是一个长度小于等于$10^6$ 的文本串$T$ . 输入结束标志为$N=0$ . 输出格式: 对于每组数据,第一行输出模式串…
题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #include <set> #include <map> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <cstdio>…
题意:给你两个串,求用m个R,n个D能组成多少个包含这两个串 题解:先构造一个AC自动机记录每个状态包含两个串的状态, 状态很容易定义 dp[i][j][k][status]表示在AC自动机K这个节点 使用了 i 个D,j个R ,状态为status的方案数. 然后直接DP即可. #include <set> #include <map> #include <stack> #include <queue> #include <cmath> #inc…
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; const int mxn=1e7+5; char str[mxn],p[80]; queue<int > q; namespace Trie { int tot,fail[mxn],val[mxn]; int t[mxn][26]; void ins(char *s) { int len=st…
题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N]; struct AC_Automaton { int cnt,q[N],val[N],fail[N],las[N],son[N][S]; // struct Node // { // int val,las,fail,son[S]; // Node *son[S];//指针太麻烦了.. // Node()…
考虑两一个暴力 1 因为询问\([a,b]\)可以拆成\([1,b]\)-\([1,a-1]\)所以把询问离线,然后就是求\([1,x]\)中被\(S_i\)包含的串的数量.考虑当\([1,x-1]->[1,x]\)时我们把\(S_x\)结束节点在fail树的子树加1.然后询问就是求\(S_i\)在AC自动机上跑时经过所有点的点权用树状数组维护.设\(\sum{len[S_i]}=L\)这样的复杂度就是\(O(mLlogL)\)无法通过此题. 2 依然离线.这次我们把\(S_i\)放在fail树…
题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子.   分析:跟以前做过的那两题差不多,不过这个不让取余....不过考虑到字符长度也不大,最多也就50,所以使用一般的dp也可以.ps.在做高高精度运算的时候输出答案竟然正着输出了....然后就一直WA....确实有些时间没有敲过高精度题目了.   代码如下: =====================…
题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个节点. 然后构建Trie图.fail[]有一个重要意义是: 若fail[y]=x,那么y节点表示的串一定包含x节点表示的串. 于是暴力就可以自底向上查询y串中每个节点的fail[]是否直接或间接指向x 注意到每个节点的fail[]是仅指向一个节点的,于是可以反向建图fail[x]->x,这样就形成了…