这里用第一个字符串构建完成后缀自动机以后 不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1 如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后将cur节点转移到当前节点即可,再把答案加1 记住不断更新所能得到的最大值 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace…
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量Lcs来记录当前答案,如果能转移到下一个状态则Lcs++. 若不能转移说明需要重新选择状态,则不断地跳到当前状态的fa状态,如果发现能够转移就停下来,Lcs变为当前状态的len+1并转移到下一个可行状态. 这里很像AC自动机的fail指针的跳跃.因为fa状态是当前状态的后缀,已经被匹配过,而fa状态有…
LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at least on…
用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include<cstring> #include<string> #include<iostream> #include<cmath> #include<vector> #include<algorithm> #define maxn 250050 usi…
题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长可以匹配的子串(用maxx[]数组存下) 但是在后缀自动机上面有些节点没有走过,但是是某些走过的点的父亲节点因此也是有值的 for (int i = tot; i; i--) maxx[fail[i]] = max(maxx[fail[i]], min(len[fail[i]], maxx[i]))…
题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 确实比后缀数组快多了(废话→_→). \(Description\) 求两个字符串最长公共子串 \(Solution\) 对串A建立后缀自动机. A的SAM中包含A的所有子串,且根到每个节点的路径都是A的子串.如果B(的一部分?)匹配到了SAM上的某个节点,那么这便是AB的公共子串.求出这些点的max(len)即可. 用串B在SAM上逐位匹配,如果匹配,就继续沿着匹配边走: 否则,为了匹配当…
题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对于n个串的最长公共子串,这要把这些串连在一起,中间用"$"这类的特殊符号分隔一下. 先求后缀数组,再求最长公共前缀,取相邻两个且属于不同串的sa的最大LCP即可. 原理就是:这样把分属两个串的LCP都跑了一遍,也就是相当于把所有子串走了一遍, 只不过走这些子串是经过层层预处理过的. 下面提…
后缀自动机处理多字符串字串相关问题. 首先,和后缀数组一样,用分割符连接各字符串,然后建一个后缀自动机. 我们定义一个节点代表的字符串为它原本代表的所有串去除包含分割符后的串.每个节点代表的字符串的数量可以用DP来计算(不能用right集合来算了). 对于原来n个串中的一个串,其所有前缀可以通过将该串放到自动机上跑来获得,对于某个前缀,其所有后缀包括在该前缀本身的节点以及parent树的祖先节点中.这样我们就获得访问某个串所有子串的技能了. 对于这道题,我们可以先建出后缀自动机,然后对于n个串中…
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对于n个后缀对应的节点打上标记,则每个结点对应的一些子串所出现的次数即为其子树内标记的个数,在后缀树上进行1遍dfs统计,之后根据答案的单调性线性扫描一遍进行统计. #include <iostream> #include <string> #include <cstring>…
转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能够走出多少个串.f[i]=sigma(f[ch[i][c])+1这个可以按Max排序之后倒着推就好了.询问的时候看一下走下去个数是否<=k,是的话就走下去,然后–k:否则就找下一条边 #include<iostream> #include<cstdio> #include<…