一个串建DAG另一个串直接跑就可以
跑的时候三种情况
第一种当前的root就有c这个出边 那么 直接跑到下一位就好
第二种当前的root没有c这个出边 但是当前root的别的状态的后缀有出边
那么不断跳fa跳到有出边即可(因为当前length(root)必然大于其length(fa)并且kmp思想 匹配了root代表的后缀那么fa也匹配了,所以肯定是length(fa)+1)
如果跳到root = 0说明没有这个子串 所以领root=1重新开始即可
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 400000+100;
struct node{
int ch[26];
int len,fa;
node(){
memset(ch,0,sizeof(ch));
len = fa = 0;
}
}dian[maxn];
int tot = 1,las = 1;
void add(int c){
int p = las;
int np = las = ++tot;
dian[np].len =dian[p].len+1;
for(;p&&!dian[p].ch[c];p = dian[p].fa)dian[p].ch[c] = np;
if(!p)dian[np].fa = 1;
else{
int q = dian[p].ch[c];
if(dian[q].len==dian[p].len+1){
dian[np].fa = q;
}
else{
int nq = ++tot;
dian[nq] = dian[q];
dian[nq].len = dian[p].len+1;
dian[q].fa = dian[np].fa = nq;
for(;p&&dian[p].ch[c]==q;p = dian[p].fa)dian[p].ch[c] = nq;
}
}
}
char s1[maxn];
char s2[maxn];
int maxs = 0;
void query(char * s,int len){
int rt = 1;
int now = 0;
for(int i = 0;i<len;++i){
if(dian[rt].ch[s[i]-'a']){
now++;
rt = dian[rt].ch[s[i]-'a'];
// cout<<1<<endl;
}
else{
for(;rt&&!dian[rt].ch[s[i]-'a'];rt = dian[rt].fa);
if(!rt){
rt = 1;
now = 0;
// cout<<2<<endl;
}
else{
now = dian[rt].len+1;
rt = dian[rt].ch[s[i]-'a'];
// cout<<3<<endl;
}
}
// cout<<i<<":"<<dian[rt].len<<endl;
maxs = max(now,maxs);
}
}
int main(){
scanf("%s%s",s1,s2);
int len1 = strlen(s1);
int len2 = strlen(s2);
for(int i = 0;i<len1;++i){
add(s1[i]-'a');
}
query(s2,len2);
cout<<maxs<<endl;
}