![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
后缀自动机
行走天涯的豆沙包
人生天地间,忽如远行客。
展开
-
后缀自动机——Boring counting
题解: 统计每个子串的最右位置和最左位置,在这个区间(左闭右开)里我们一定能够保证我们每个子串出现了2次。 #include <bits/stdc++.h> using namespace std; const int maxn=2e5+10; const int maxc=27; typedef long long ll; struct Suffix_Automaton { int next[maxn<<1][maxc]; //状态转移(尾部加一个字符的下一个状态)原创 2020-07-27 11:27:12 · 145 阅读 · 0 评论 -
后缀自动机——Lexicographical Substring Search
题解: 对串建立后缀自动机过后,top排序之后,计算每种状态有多少种转移的可能。然后和主席数找第k大的方法一样。 #include <bits/stdc++.h> using namespace std; const int maxn=2e5+10; const int maxc=27; typedef long long ll; struct Suffix_Automaton { int next[maxn<<1][maxc]; //状态转移(尾部加一个字符的下一个状态)原创 2020-07-24 23:04:38 · 134 阅读 · 0 评论 -
后缀自动机——Substrings
题解: 让我们找长度为x的子串出现的最大次数。我们先建立sam,然后把节点top序。我们知道endpos是一些出现相同次数和相同结束位置的集合。所以我们定义fif_ifi为长度为i的子串出现的最大次数。我们因为知道长度fi>=fjf_i>=f_jfi>=fj,i<ji<ji<j的时候,所以我们只需要更新f[len[i]]f[len[i]]f[len[i]]就可以了。f[len[i]]=max(endpos[i],f[len[i]])f[len[i]]=max(end原创 2020-07-23 11:57:42 · 242 阅读 · 0 评论 -
后缀自动机——Longest Common Substring II
题解: 上一个题是两个串的最长公共子串长度。这道题是多个串来求最长公共子串长度。我们记录匹配到每个状态的时候,到这个状态匹配的最大长度是多少。最后按照top序找最大的最小值。 收获了一个sam的板子。 #include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; const int maxc=27; typedef long long ll; struct Suffix_Automaton { int next[原创 2020-07-22 23:08:49 · 146 阅读 · 0 评论 -
后缀自动机——Longest Common Substring
题解: 让我们匹配两个串的最长公共子串。求这个长度。我们把a串建立后缀自动机,然后按照b串依次去匹配,每次记录匹配值,并且取最大。在匹配的时候,如果当前状态可以转移 则答案++,否则的话我们就去找后缀链,看能不能匹配上,如果有代表有这个边的出边,则答案就是lenmax(now)+1,now是当前状态,如果最后都没有匹配上,答案为0,并状态从1重新开始匹配。 #include <bits/stdc++.h> using namespace std; const int maxn = 2e6+10;原创 2020-07-22 20:39:50 · 120 阅读 · 0 评论 -
后缀自动机——P3804
题解: 尝试学习sam第三次 ,这次我终于好了。 再次写这道题是跑slink的拓扑序得到的。这里说一下,如果我们从S状态到T状态跑,我们找的是x这个子串,在跑这个状态的过程中相当于x就是这些后缀的前缀,而我们每按照slink这个树跑一个状态我们后缀就会多一个数,子串出现次数也就会++,比如我们d,cd,bcd,abcd中d都是他们的子串所以我们每个子串出现的次数就是slink树中子树的大小。 #include <bits/stdc++.h> using namespace std; const原创 2020-07-22 20:15:17 · 103 阅读 · 0 评论 -
后缀自动机——所有子串个数
传送门 题解: 背过题,sam构造理解还是好难,求子串个数一个是跑DAG,一个就是len[last]−len[fa[last]]len[last]-len[fa[last]]len[last]−len[fa[last]] #include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; long long res=0; struct SuffixAutoMation { int last=1,cnt=1;//cn原创 2020-06-14 13:03:58 · 266 阅读 · 0 评论 -
后缀自动机——P3804
传送门 题解: 这道题是找是找所有子串出现的次数,就是在建好的图上面跑DAG。 #include <bits/stdc++.h> using namespace std; const int maxn = 1e6+10; char s[maxn]; struct SuffixAutoMation { int last,cnt;//cnt表示状态 int trans[maxn<<1][26],slink[maxn<<1],l[maxn<<1];原创 2020-06-10 19:29:17 · 111 阅读 · 0 评论