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 ,求出最长 ...
随机推荐
- bootstrap里的fileimput的小问题
fileinput 是bootstrap 里面一个非常好的插件 于是我很开心的开始的使用了 $("#file_upload").fileinput({ uploadUrl: &qu ...
- x86 保护模式 十 分页管理机制
x86 保护模式 十 分页管理机制 8.386开始支持分页管理机制 段机制实现虚拟地址到线性地址的转换,分页机制实现线性地址到物理地址的转换.如果不启用分页,那么线性就是物理地址 一 分页管 ...
- Thanks for your encourage!
将近三个月的学习,我的努力换回了代表荣誉的小黄衫,这令我很开心啊...我想是不是要写点什么来表达自己的心情呢=,= 于是就有了以下文字ahhhhhh... 学习心得: (1)学习中总会有失败和成功, ...
- oracle dual表用途及结构详解
dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录.我们可以用它来做很多事情,如下: 1.查看当前用户,可以在 SQL Plus中执行下面语句 sele ...
- LaTeX:毕设模版设计问题1 各级标题编号设为黑体
我用'titlesec'宏包设计各级标题格式指定字体为黑体,结果标题编号仍为Times New Roman .
- 【bzoj5110】Yazid的新生舞会
这里是 $THUWC$ 选拔时间 模拟赛的时候犯 $SB$ 了,写了所有的部分分,然后直接跑过了 $4$ 个大样例(一个大样例是一个特殊情况)…… 我还以为我非常叼,部分分都写对了,于是就不管了…… ...
- spring中MessageSource的配置使用方法2--ReloadableResourceBundleMessageSource
如何在spring mvc框架中实现MessageSource来管理国际资源文件呢 如下: 1.在applicationContext.xml文件内配置如下 <span style=" ...
- 瞄一眼CopyOnWriteArrayList(jdk11)
CopyOnWriteArrayList是ArrayList线程安全的变体.使用写时复制策略进行修改操作. 与之前版本较明显的区别是,jdk11中用来保护所有设值方法(mutator)的Reentra ...
- codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新
DZY Loves Fibonacci Numbers Time Limit:4000MS Memory Limit:262144KB 64bit IO Format:%I64d &a ...
- FOJ Problem 2257 Saya的小熊饼干
...