题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长可以匹配的子串(用maxx[]数组存下) 但是在后缀自动机上面有些节点没有走过,但是是某些走过的点的父亲节点因此也是有值的 for (int i = tot; i; i--) maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]))…
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 样例就觉得不能更眼熟啊...好像之前用后缀数组做过一次 然后发现后缀自动机真的好好写啊...(当然当时学后缀数组的时候也这么认为... 这道题直接把第一个串放到后缀自动机里 第二个串在上面做匹配,但是要注意匹配的时候不能乱搞... 刚开始写了一个类似KMP的东西...想想不对啊 毕竟有些节点的深度是不对的 然而后来发现,我们可以用一个变量tem来保存当前的长度值 如果可以继续匹配,这个值就+1 否则就开始用fail指针不停地退,直到退…
http://www.spoj.com/problems/LCS/ 题目:求两个串的最长公共子串 参考:https://www.cnblogs.com/autoint/p/10345276.html: 分析: 给定两个字符串 S 和 T ,求出最长公共子串,公共子串定义为在 S 和 T 中 都作为子串出现过的字符串 X . 我们为字符串 S 构造后缀自动机. 我们现在处理字符串 T ,对于每一个前缀都在 S 中寻找这个前缀的最长后缀.换句话 说,对于每个字符串 T 中的位置,我们想要找到这个位置…
题意:求n个串的最长公共子串,子串出现在一个串中可以是它的反转串出现.总长<=10^4. 题解: 对于每个串,把反转串也连进去.二分长度,分组,判断每个组. #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; *; int n,sl,cl,c[N],rk[N],sa[N],Rs[N],wr[N],y[N],h[N],st…
这里串最多有10个,找所有串的最长公共子串 这里后缀自动机做,以第一个串建立后缀自动机,后面的串一个个去匹配,每次得到当前串在可到达状态上所能得到的最长后缀长度 拿所有串匹配后得到的结果进行计算 #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define M 26 #define N 200100 char str[N]; struct SamNode{ Sa…
这其实是道水题... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4032 (luogu)https://www.luogu.org/problemnew/show/P4112 题解: Task 1 \(O(n^2)\)做法无数(也有不用SAM的\(O(n^2)\)做法),我讲一下我的做法. 直接对B串建后缀自动机,用A串在上面跑,而且是像求两个串的最长公共子串那样跑,如果遇到失配了就拿当前长度\(+1\)更新答案.但…
题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. 随意做.这里面只写一下我对后缀自动机做法的理解. 首先,我们假设两个串分别为A串和B串,我们先对建立出A串的后缀自动机,然后对于B串的每一位,我们进行如下的操作:首先从第1位开始,Parent树上的位置在root,那么对于每一次操作,如果当前结点的字符可以匹配当前B串中所考虑到的字符,那么自然就l…
题目链接:http://www.spoj.com/problems/LCS2/ 其实两个串的LCS会了,多个串的LCS也就差不多了. 我们先用一个串建立后缀自动机,然后其它的串在上面跑.跑的时候算出每一个位置能往左扩展的最大长度也就是LCS. 于是对于每一个状态维护mx数组,表示当前串与SAM在此状态的LCS值.对于一个状态取所有mx中的最小值,然后答案就是所有状态最小值中的最大值,证明显然. 两个串的时候不用拿一个状态更新其祖先状态,但是这里需要.SAM是一个DAG图,我们通过l数组来基数排序…
题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwer. 法一:kmp 在第一个串中枚举答案串的开头位置,与其余\(n-1\)个串做\(kmp\). 法二:后缀数组 将\(n\)个串拼接起来.二分答案\(len\),将\(height\)分组,\(check\)是否有一组个数\(\geq len\)且落在\(n\)个不同的串中. 注意:\(n\)个串…
又学到一个\(SAM\)的新套路QvQ 思路 考虑用其中的一个串建个\(SAM\),然后用其他的串在上面匹配,匹配时更新答案 首先有一个全局变量\(len\),表示当前已匹配的长度.假设目前在点\(u\),转移方式如下(根节点为\(1\)): 如果没有对应的转移边,就走后缀连接,\(u=suflink(u)\),并令\(len=maxlen(suflink(u))\).否则走对应的转移边,同时\(len++\).如果一直没有对应的转移边,即到最后发现\(u=0\),就把\(u\)置为\(1\),…