spoj 1811 LCS - Longest Common Substring (后缀自己主动机)
spoj 1811 LCS - Longest Common Substring
题意:
给出两个串S, T, 求最长公共子串。
限制:
|S|, |T| <= 1e5
思路:
dp O(n^2) 铁定超时
后缀数组 O(nlog(n)) 在spoj上没试过,感觉也会被卡掉
后缀自己主动机 O(n)
我们考虑用SAM读入字符串B;
令当前状态为s,同一时候最大匹配长度为len;
我们读入字符x。假设s有标号为x的边,那么s=trans(s,x),len = len+1;
否则我们找到s的第一个祖先a。它有标号为x的边。令s=trans(a,x),len=Max(a)+1;
假设没有这种祖先,那么令s=root,len=0;
在过程中更新状态的最大匹配长度。
详情參考clj论文
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 3 * 1e5;
char S[N], T[N]; struct SAM {
struct Node {
int fa, ch[27];
int val;
void init() {
fa = val = 0;
memset(ch, 0, sizeof(ch));
}
} node[2 * N]; int tot;
int new_node() {
node[++tot].init();
return tot;
} int root, last;
void init() {
tot = root = last = 1;
node[0].init();
node[1].init();
} void add(int x) {
int p = last;
int np = new_node(); node[np].val = node[p].val + 1;
while(p && node[p].ch[x] == 0){
node[p].ch[x] = np;
p = node[p].fa;
}
if(p == 0) node[np].fa = root;
else {
int q = node[p].ch[x];
if(node[p].val + 1 == node[q].val)
node[np].fa = q;
else {
int nq = new_node(); node[nq].val = node[p].val + 1;
memcpy(node[nq].ch, node[q].ch, sizeof(node[q].ch));
node[nq].fa = node[q].fa;
node[q].fa = node[np].fa = nq;
while(p && node[p].ch[x] == q) {
node[p].ch[x] = nq;
p = node[p].fa;
}
}
}
last = np;
}
void debug() {
for(int i = 1; i <= tot; ++i) {
printf("id=%d, fa=%d, step=%d, ch=[ ", i, node[i].fa, node[i].val);
for(int j = 0; j < 26; ++j) {
if(node[i].ch[j])
printf("%c,%d ", j+'a', node[i].ch[j]);
}
puts("]");
}
} void gao();
} sam; void SAM::gao() {
int len_s = strlen(S);
int len_t = strlen(T); init();
for(int i = 0; i < len_s; ++i) {
add(S[i] - 'a');
}
//debug();
int p = root;
int ans = 0;
int tmp = 0;
for(int i = 0; i < len_t; ++i) {
if(node[p].ch[T[i] - 'a']) {
++tmp;
p = node[p].ch[T[i] - 'a'];
} else {
while(p && node[p].ch[T[i] - 'a'] == 0)
p = node[p].fa;
if(p) {
tmp = node[p].val + 1;
p = node[p].ch[T[i] - 'a'];
} else {
p = root;
tmp = 0;
}
}
ans = max(ans, tmp);
}
printf("%d\n", ans);
} int main() {
scanf("%s%s", S, T);
sam.gao();
return 0;
}
spoj 1811 LCS - Longest Common Substring (后缀自己主动机)的更多相关文章
- SPOJ 1811 LCS - Longest Common Substring
思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成两个串就有双倍经验了 代码 #include <cstdio> #includ ...
- 【刷题】SPOJ 1811 LCS - Longest Common Substring
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- SPOJ1811 LCS - Longest Common Substring(后缀自动机)
A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...
- 后缀自动机(SAM) :SPOJ LCS - Longest Common Substring
LCS - Longest Common Substring no tags A string is finite sequence of characters over a non-empty f ...
- spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)
spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...
- spoj1811 LCS - Longest Common Substring
地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags A string is finite ...
- 【SP1811】LCS - Longest Common Substring
[SP1811]LCS - Longest Common Substring 题面 洛谷 题解 建好后缀自动机后从初始状态沿着现在的边匹配, 如果失配则跳它的后缀链接,因为你跳后缀链接到达的\(End ...
- SPOJ 10570 LONGCS - Longest Common Substring
思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成多组数据就有三倍经验了 代码 #include <cstdio> #inclu ...
- SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机
Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...
随机推荐
- 让读者快速了解RocketMQ消息中间件需要解决哪些问题
本文首先引出消息中间件通常需要解决哪些问题,在解决这些问题当中会遇到什么困难,Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件否可以解决,规范中如何定义这些问题.然后 ...
- [python学习篇] uiautomator xiaocong
Skip to content This repository Pull requests Issues Marketplace Gist Sign out Watch103 ...
- JavaScriptCore 简介
转自http://esoftmobile.com/2013/06/19/integrating-javascript-into-native-applications/ Integrating Jav ...
- Welcome-to-Swift-01基础部分
Swift 是 iOS 和 OS X 应用开发的一门新语言.然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的. Swift 的类型是在 C ...
- kb-07线段树--10--dfs序建树
/* hdu3974 dfs序建树,然后区间修改查询: */ #include<iostream> #include<cstdio> #include<cstring&g ...
- HDU——1062Text Reverse(水题string::find系列+reverse)
Text Reverse Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- 用Keepalived搭建双Nginx server集群,防止单点故障
综述: 浏览器访问虚拟IP: 192.168.1.57, 该虚拟IP被Keepalived接管,两个Keepalived进程分别运行在物理IP为192.168.1.56和192.168.1.59服务器 ...
- ELK安装文档
ELK安装文档: http://cuidehua.blog.51cto.com/5449828/1769525 如何将客户端日志通过ogstash-forwarder发送给服务端的logstash h ...
- TYVJ 1305 最大子序和 ++ 烽火传递
描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入 ...
- jsp文件放在WebRoot下还是WebInfo下
观点一:(较为赞同) 安全性不是真正的原因,因为jsp是要解析后才显示到浏览器的,即使用户知道你jsp的路径,也不可能通过浏览器看到jsp源码的,而如果是通过其它手段入侵服务器的话,放在WEB-INF ...