SPOJ LCS 后缀自动机找最大公共子串
这里用第一个字符串构建完成后缀自动机以后
不断用第二个字符串从左往右沿着后缀自动机往前走,如能找到,那么当前匹配配数加1
如果找不到,那么就不断沿着后缀树不断往前找到所能匹配到当前字符的最大长度,然后将cur节点转移到当前节点即可,再把答案加1
记住不断更新所能得到的最大值
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define M 26
#define N 600000
int cnt;
char s1[N] , s2[N]; struct SamNode{
SamNode *son[M] , *f;
int l;
}sam[N] , *root , *last; void init()
{
memset(sam , , sizeof(sam));
root = last = &sam[cnt=];
} void add(int x)
{
SamNode *p = &sam[++cnt] , *jp = last;
p->l = jp->l+;
last = p;
for(; jp&&!jp->son[x] ; jp=jp->f) jp->son[x] = p;
if(!jp) p->f = root;
else{
if(jp->l+ == jp->son[x]->l) p->f = jp->son[x];
else{
SamNode *r = &sam[++cnt] , *q = jp->son[x];
*r = *q;
r->l = jp->l+; q->f = p->f = r;
for(; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r;
}
}
} int solve(int len)
{
int ret = , maxn=;
SamNode *cur = root;
for(int i= ; i<len ; i++){
int x = s2[i]-'a';
if(cur->son[x]){
ret++;
cur = cur->son[x];
}
else{
while(cur && !cur->son[x]) cur = cur->f;
if(!cur) cur = root , ret=;
else{
ret = cur->l+;
cur = cur->son[x];
}
}
maxn = max(maxn , ret);
}
return maxn;
} int main()
{
// freopen("in.txt" , "r" , stdin);
// freopen("out.txt" , "w" , stdout);
scanf("%s%s" , s1 , s2);
init();
int len1 = strlen(s1) , len2 = strlen(s2);
for(int i= ; i<len1 ; i++) add(s1[i]-'a');
int ret = solve(len2);
printf("%d\n" , ret);
return ;
}
SPOJ LCS 后缀自动机找最大公共子串的更多相关文章
- [SPOJ1811]Longest Common Substring 后缀自动机 最长公共子串
题目链接:http://www.spoj.com/problems/LCS/ 题意如题目,求两个串的最大公共子串LCS. 首先对其中一个字符串A建立SAM,然后用另一个字符串B在上面跑. 用一个变量L ...
- SPOJ - LCS 后缀自动机入门
LCS - Longest Common Substring A string is finite sequence of characters over a non-empty finite set ...
- SPOJ LCS 后缀自动机
用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...
- 多个串的最长公共子串 SPOJ - LCS2 后缀自动机
题意: 求多个串的最长公共子串 这里用的是O(n)的后缀自动机写法 我后缀数组的专题有nlog(n)写法的 题解: 对于其中的一个串建立后缀自动机 然后对于后缀自动机上面的每一个节点求出每一个节点最长 ...
- POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀自动机)
题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 确实比后缀数组快多了(废话→_→). \(Description\) 求两个字符串最长公共子串 ...
- POJ 2217 (后缀数组+最长公共子串)
题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 后缀数组解法是这类问题的模板解法. 对 ...
- bzoj 3473 后缀自动机多字符串的子串处理方法
后缀自动机处理多字符串字串相关问题. 首先,和后缀数组一样,用分割符连接各字符串,然后建一个后缀自动机. 我们定义一个节点代表的字符串为它原本代表的所有串去除包含分割符后的串.每个节点代表的字符串的数 ...
- SPOJ NSUBSTR (后缀自动机)
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...
- SPOJ 7258 (后缀自动机)
转载:http://hzwer.com/4492.html 给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 搞出后缀自动机 dp处理出每个点往下走能 ...
随机推荐
- RedHat7.2安装matplotlib——之Python.h:没有那个文件或目录
按理说运行下面一句就可以安装了 pip install matplotlib 但是对于我的redhat7.2+python2.7.5,报了下面的错误 _posixsubprocess.c:3:20: ...
- Java提供的序列化和反序列化
序列化:是指将Java对象转换为二进制数据. 反序列化:将二进制数据转换为Java对象. 与序列化功能相关的类有: java.io.Serializable; java.io.ObjectOutput ...
- AJPFX:实现递归统计文件夹的总大小
class Statistical { public static void main(String[] args) { Scanner sc = new Scanner(Syst ...
- os模块详解2
1.os.getenv('HOME') 读取操作系统环境变量HOME的值. 2.os.environ 返回操作系统所有的环境变量. 3.os.environ.setdefault(‘a’,‘b’) ...
- [python3]PyCharm编辑器
简介 Python有丰富的开发工具,本教程不一一进行介绍,只推荐大家使用PyCharm,因为python开发者都在用它,但缺点就是消耗电脑资源,如果你电脑配置低,就会比较卡 下载 下载地址: http ...
- DHCP server工作原理
1.CLIENT首先发出广播的DHCPDISCOVER报文,广播的目的是让DHCP SERVER能够收到这个请求报文.在这个报文中,CLIENT可以在"选项"字段中加入" ...
- iOS开发内购全套图文教程
2015年最全的内购图文教程,首先是填各种资料,最后是代码,废话不多说,直接上图 ======================第一部分协议=============== 第一步 第二步 第三步 第四步 ...
- 应用程序员眼中的数据库管理系统:API+数据库语言
应用程序员眼中的数据库管理系统:API+数据库语言 sqlite3_open_v2 https://www.cnblogs.com/cchust/p/5121559.html
- HDU 4281 (状态压缩+背包+MTSP)
Judges' response Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- centos6上安装mysql8.0版本
本博客是采用yum源的方式安装,非常的方便和快捷.(redhat 与centos7 等操作系统都可以采用此方法,步骤大体一致) mysql官网地址: https://dev.mysql.com 开 ...