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 (后缀自己主动机)的更多相关文章

  1. SPOJ 1811 LCS - Longest Common Substring

    思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成两个串就有双倍经验了 代码 #include <cstdio> #includ ...

  2. 【刷题】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 ...

  3. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  4. 后缀自动机(SAM) :SPOJ LCS - Longest Common Substring

    LCS - Longest Common Substring no tags  A string is finite sequence of characters over a non-empty f ...

  5. spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)

    spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...

  6. spoj1811 LCS - Longest Common Substring

    地址:http://www.spoj.com/problems/LCS/ 题面: LCS - Longest Common Substring no tags  A string is finite ...

  7. 【SP1811】LCS - Longest Common Substring

    [SP1811]LCS - Longest Common Substring 题面 洛谷 题解 建好后缀自动机后从初始状态沿着现在的边匹配, 如果失配则跳它的后缀链接,因为你跳后缀链接到达的\(End ...

  8. SPOJ 10570 LONGCS - Longest Common Substring

    思路 和SPOJ 1812 LCS2 - Longest Common Substring II一个思路,改成多组数据就有三倍经验了 代码 #include <cstdio> #inclu ...

  9. SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机

    Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...

随机推荐

  1. [python][oldboy]字符串 format

    #coding=utf8 def format(self, *args, **kwargs): # known special case of str.format """ ...

  2. ICM Technex 2018 and Codeforces Round #463 (Div. 1 + Div. 2, combined)

    靠这把上了蓝 A. Palindromic Supersequence time limit per test 2 seconds memory limit per test 256 megabyte ...

  3. tzcacm去年训练的好题的AC代码及题解

    A - Tree UVA - 548 You are to determine the value of the leaf node in a given binary tree that is th ...

  4. Map容器——TreeMap及常用API,Comparator和Comparable接口

    TreeMap及常用API ①   TreeMap类通过使用红黑树实现Map接口; ②   TreeMap提供按排序顺序存储键/值对的有效手段,同时允许快速检索; ③   不像散列(HashMap), ...

  5. iOS学习笔记35-社交分享

    一.社交分享 现在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.人人网等,其实从iOS6.0开始苹果官方就内置了Social.framework专门来实现社 ...

  6. HDU——2068RPG的错排(错排公式)

    RPG的错排 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  7. setsockopt等高级使用

    参考: setsockopt函数使用http://hi.baidu.com/yelangdefendou/item/74161d0f384abd3c4ac4a316http://blog.csdn.n ...

  8. Python Base Three

    //sixth day to study python(2016/8/7) 32. In python , there are have an special type dictionary , it ...

  9. iOS-文件断点续传

    * 移动客户端在和服务器交互的时候,上传和下载使用十分广泛. * 在我们下载文件的时候,我们在点击暂停的时候可以暂停下载,点击下载的时候可以继续下载,这个功能如何实现? * 下载进度条如何显示? 先大 ...

  10. ideaaaaaaaaa

    数据库proxy:可以用作自动化数据逆向SQL test4j/jtester: