题目链接:SP1811 LCS
对串A建立SAM,计算每一个b字符结尾的答案。
对于当前字符有向下的转移就直接 len++,跳过去。
否则一直向上跳父亲。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
char a[N],b[N]; int na,nb;
struct SAM{
int cnt=1,last=1;
struct node{int ch[26],len,fa;}d[N];
inline void insert(int c){
int p=last,np=last=++cnt; d[np].len=d[p].len+1;
for(;p&&!d[p].ch[c];p=d[p].fa) d[p].ch[c]=np;
if(!p) d[np].fa=1;
else{
int q=d[p].ch[c];
if(d[q].len==d[p].len+1) d[np].fa=q;
else{
int nq=++cnt;
d[nq]=d[q],d[nq].len=d[p].len+1,d[q].fa=d[np].fa=nq;
for(;p&&d[p].ch[c]==q;p=d[p].fa) d[p].ch[c]=nq;
}
}
}
inline void build(){for(int i=1;i<=na;i++) insert(a[i]-'a');}
void calc(){
int p=1,res=0,len=0;
for(int i=1;i<=nb;i++){
int k=b[i]-'a';
if(d[p].ch[k]) len++,p=d[p].ch[k];
else{
for(;p&&!d[p].ch[k];p=d[p].fa);
if(p) len=d[p].len+1,p=d[p].ch[k];
else len=0,p=1;
}
res=max(res,len);
}
cout<<res;
}
}sam;
signed main(){
scanf("%s %s",a+1,b+1); na=strlen(a+1),nb=strlen(b+1);
sam.build(); sam.calc();
return 0;
}