后缀自动机
LowestJN
强省弱OIer
展开
-
[HDU4622]Reincarnation 后缀自动机
题意求给定字符串的[l,r]区间内不同的子串个数。注意到n只有2000,对每个后缀建后缀自动机,边网后缀自动机里插入字符,边几率子串个数,对于询问O(1)输出。#include <cstdio> #include <cstring> #include <string> #include <iostream> #define N 2010using namespace std;int n,t,m,An原创 2017-01-24 20:26:19 · 436 阅读 · 0 评论 -
[Hash 后缀自动机] LOJ#6173. Samjia 和矩阵
枚举子矩阵的宽度 不同宽度的子矩阵一定本质不同,相同宽度的子矩阵有 n2" role="presentation">n2n2n^2 个,把每个宽度为 k" role="presentation">kkk 的子矩阵每一行hash一下,就变成了一个字符串,求本质不同的个矩阵用广义后缀自动机就行了 #include #include #include #include using name原创 2018-01-26 16:56:11 · 374 阅读 · 0 评论 -
[后缀自动机 阈值] LOJ#6031. 「雅礼集训 2017 Day1」字符串
对 kk 阈值 如果 k≤Sk\le S 枚举询问串的每个子串,在后缀自动机上找到对应的节点就可以了 O(qkk2logn)O({q\over k}k^2\log n) 如果 k>Sk>S 枚举询问串的前缀,找到对应节点,每个和这个前缀相关的询问是这个前缀的后缀,在fail树上倍增 O(qk(k+mlogn))O({q\over k}(k+m\log n)) 这个log我卡不掉,只能原创 2018-01-24 14:05:34 · 418 阅读 · 0 评论 -
[BZOJ2555][LCT][后缀自动机]SubString
题意给定一个初始字符串,要求支持两种操作,往字符串后加一个字符串和求一个字符串的出现次数。可以对字符串建后最自动机,那么一个子串x的出现次数就是|right(x)|, |right(x)|可以用fail树维护。 那么每次往字符串后面加字符串,暴力维护|right(x)|时间复杂度会被卡成O(n^2)。 这时候就要用LCT来维护了所以复杂度就变成O(nlogn)(虽然感觉LCT的复杂度很玄学,但原创 2017-02-05 22:25:27 · 356 阅读 · 0 评论 -
[后缀自动机 DP] LOJ#6071. 「2017 山东一轮集训 Day5」字符串
fi,jf_{i,j} 表示前 ii 个串,以 jj 结尾的可接受的字符串的个数。那么DP的转移可以用后缀自动机转移#include <cstdio> #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int N=4000010,P=1e9+7;int n,cnt=1,len; i原创 2017-10-13 07:58:57 · 867 阅读 · 0 评论 -
[Notes][模板] 记(瞎写) · 后缀自动机
SAM后缀自动机,就是一个能接受一个字符串所有后缀的自动机,本质是字典树。考虑一个能接收一个字符串所有后缀的数据结构,显然字典树可以——只要把所有后缀加到字典树中,但是这样节点的个数是O(N2)O(N^2)的,接受不了,还有就是后缀树,但是后缀树的构造方法极其麻烦。这个时候后缀自动机就是很好的选择(事实上它也具备字典树和后缀树的性质)构造后缀自动机的构造不能说简单但是好记 可以看有具体证明的clj原创 2017-07-16 17:02:23 · 864 阅读 · 0 评论 -
[后缀自动机][分块]HackerRank Week of Code 30 .Substring Queries
题意是给出n个字符串,有Q组询问,每次询问第x和第y个字符串的最长公共子串感觉这题会后缀自动机就挺水了… 因为字符串总长<=1e5,所以第一反应就可以分块 首先对每个串建后缀自动机因为后缀自动机可以O(串长)求出两个串的最长公共子串,所以如果询问的两个串有一个串长小于sqrt(总串长),那么直接在较长串的后缀自动机上查询就可以了。那如果有两个串都大于sqrt(总串长)呢 依然可以暴力查询,只不原创 2017-07-14 18:10:17 · 774 阅读 · 0 评论 -
[Codeforces][后缀自动机]Helvetic Coding Contest 2017 . I Fake News (hard)
一看是字符串题,就想一想怎么在后缀自动机上搞有一个跟BZOJ3238 差异差不多的思路,建出原串反串的后缀自动机,那么每个子串的lcp就是对应节点的lca,那么lcp出现次数就是这个节点的right集合,拷了拷之前的代码,改一改就过了……#include <cstdio> #include <iostream> #include <cstring> #include <string> #define原创 2017-05-30 21:21:56 · 684 阅读 · 0 评论 -
[BZOJ3473][后缀自动机][启发式合并]字符串
首先建立广义自动机对于自动机上的每一个节点,开一个set,记录它能接受的所有子串的编号(不要用multiset,会出现重复的编号),然后在fail树上dfs求出从根节点到当前节点这条路径代表的子串出现在几个字符串中(利用fail树的性质),只有对于每个节点启发式合并它的所有儿子的set就行了#include <cstdio> #include <iostream> #include <algorit原创 2017-03-15 17:49:51 · 1058 阅读 · 0 评论 -
[BZOJ2806][Ctsc2012][后缀自动机][队列优化][DP]Cheat
题意略……因为要让L的长度最大,可以二分L,然后check 要求在L的限制下最大的匹配长度,可以DP。 令f[i]表示前i个字符的最大匹配长度,g[i]表示1~i可以匹配的最长后缀的长度,则f[i]=max{f[j]+i-j | i-g[i]<=j<=1-L} i-g[i]是单调不降的,所以这个DP可以用单调队列优化#include <cstdio> #include <iostream> #原创 2017-02-15 18:35:31 · 412 阅读 · 0 评论 -
[BZOJ3238][Ahoi2013][后缀自动机][树形DP]差异
题意∑len(Ti)+∑len(Tj)\sum len(Ti)+\sum len(Tj)可以O(1)O(1)计算出来。 主要就是求lcp(Ti,Tj)lcp(Ti,Tj) 将字符串反过来,建立后缀自动机,parent树就是原串的后缀树,lcp就是对应节点的lca,树形DP。 这幅图来自一篇不错的后缀自动机讲解#include <cstdio> #include <iostream> #incl原创 2017-01-31 11:13:29 · 1101 阅读 · 0 评论 -
[BZOJ2882][后缀自动机]工艺
后缀自动机裸题 将序列复制两遍建后缀自动机 每次贪心地走最小的边 走N次得到答案#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <map> #define N 1000010using namespace std;struct SAM_{ int fail[N],st原创 2017-01-30 22:57:11 · 514 阅读 · 0 评论 -
[BZOJ3998][TJOI2015]弦论 后缀自动机
题意求给定字符串的第k大子串看这里其实知道后缀自动机的性质后推敲一下还是蛮好理解的。他在胡说#include <cstdio> #include <string> #include <cstring> #include <iostream> #define N 500010using namespace std;struct SAM_{ int next[N<<2][26],fail[N<<原创 2017-01-30 19:23:52 · 527 阅读 · 0 评论 -
[后缀自动机] BZOJ5084. hashit
陈老师神题 考虑怎么删除,每次插入最多增加两个节点,那么删除只要删除两个节点就好了 加入字符时会改变两个值,一个是nxt一个是fail 当我们删除节点 u" role="presentation">uuu 时,如果一个点 v" role="presentation">vvv 的fail是 u" role="presentation">uuu,那么要把 failv" role="present原创 2018-01-28 19:04:58 · 608 阅读 · 0 评论