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 once in a string.
Now your task is simple, for two given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
Input
The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
Input: alsdfkjfjkdsal fdjskalajfkdsla Output: 3Notice: new testcases added
题目大意:求两个串的最长公共子串。
解题思路:对第一个字符串建立后缀自动机(SAM), 然后让第二个字符串在SAM上跑就可以了。
/*
@Author: Top_Spirit
@language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
typedef pair < int, int > P ;
const int Maxn = 25e4 + 10 ;
const int INF = 0x3f3f3f3f ;
const double PI = acos(-1.0) ;
const ull seed = 133 ;
string s1, s2 ;
int len1, len2 ;
struct SAM{
int son[Maxn << 1][26],step[Maxn << 1],pre[Maxn << 1];
int tot,root,last;
void add(int ch, int id){
int p = last, np = ++tot ;
last = np ;
// step[np] = step[last] + 1 ;
step[np] = id ;
for (; p && !son[p][ch]; p = pre[p]) son[p][ch] = np ;
if (!p) pre[np] = root ;
else {
int q = son[p][ch] ;
if (step[q] != step[p] + 1) {
int nq = ++tot ;
step[nq] = step[p] + 1 ;
memcpy(son[nq], son[q], sizeof(son[q])) ;
pre[nq] = pre[q] ;
pre[np] = pre[q] = nq ;
for ( ; son[p][ch] == q; p = pre[p]) son[p][ch] = nq ;
}
else pre[np] = q ;
}
}
void build(string s){
for (int i = 0; i < len1; i++){
int id = s[i] - 'a' ;
add(id, i) ;
}
}
void init(){
// memset(son, 0, sizeof(son)) ;
// memset(pre, 0, sizeof(pre)) ;
// memset(step, 0, sizeof(step)) ;
last = root = ++tot ;
}
}sa;
int main (){
cin >> s1 >> s2 ;
len1 = s1.size() ;
len2 = s2.size() ;
sa.init() ;
sa.build(s1) ;
int ans = 0, len = 0, p = sa.root ;
for (int i = 0; i < len2; i++){
int id = s2[i] - 'a' ;
if (sa.son[p][id]) {
len++ ;
p = sa.son[p][id] ;
}
else {
while (p && !sa.son[p][id]) p = sa.pre[p] ;
if (!p) p = sa.root, len = 0 ;
else {
len = sa.step[p] + 1 ;
p = sa.son[p][id] ;
}
}
ans = max(ans, len) ;
}
cout << ans << endl ;
return 0 ;
}