传送门
解析:
小声BB:vjudge上面应该出了一点问题,C++会Language Erro,C++14就没有问题。
思路:
建立其中一个串的SAM,然后拿另外一个串去匹配,能够匹配到的最大长度就是最长公共子串。
啊你问我为什么这样是对的,请回去重新学习什么是有限状态自动机。
能搞明白FSM的应该都不会问这种问题。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
typedef struct SAM_node *point;
struct SAM_node{
int len;
point fa,son[26];
SAM_node():len(0),fa(NULL){}
};
cs int N=250005;
struct SAM{
SAM_node nd[N<<1];
point now,last;
SAM():now(nd),last(nd){}
inline void push_back(char c){
c-='a';
point cur=++now;
cur->len=last->len+1;
point p=last;
for(;p&&!p->son[c];p=p->fa)p->son[c]=cur;
if(!p)cur->fa=nd;
else if(p->son[c]->len==p->len+1)cur->fa=p->son[c];
else {
point clone=++now,q=p->son[c];
*clone=*q;
clone->len=p->len+1;
q->fa=cur->fa=clone;
for(;p&&p->son[c]==q;p=p->fa)p->son[c]=clone;
}
last=cur;
}
inline int query(char *s,int len){
re int ans=0,now=0;
re point u=nd;
for(int re i=1;i<=len;++i){
if(u->son[s[i]-'a']){
u=u->son[s[i]-'a'];
ans=max(ans,++now);
continue;
}
while(u&&!u->son[s[i]-'a'])u=u->fa;
ans=max(ans,now=(u?u->len:-1)+1);u=u?u->son[s[i]-'a']:nd;
}
return ans;
}
}sam;
char s[N];int len;
signed main(){
scanf("%s",s+1);len=strlen(s+1);
for(int re i=1;i<=len;++i)sam.push_back(s[i]);
scanf("%s",s+1);len=strlen(s+1);
printf("%d",sam.query(s,len));
return 0;
}