模板题目,感觉和用AC自动机差不多,就是一个一个字符在自动机里面匹配,找不到就沿着失配边往上走,然后如果当前节点变成了null那么就不能继续匹配,就把当前设置成root然后len变成0,否则就沿着边继续走,然后把len变成当前的节点的len+1因为是失配边,所以前边的都可以匹配,变成当前的len+1
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 200;
struct node{
node *p[26], *pre;
int len;
node(){
memset(p, 0, sizeof p);
pre = NULL;
len = 0;
}
}Edges[MAXN*2+10], *ecnt=Edges+1,*root=Edges,*last=Edges;
void Insert(int w){
node *np = ecnt++;
node *p = last;
while(p&&!p->p[w])
p->p[w]=np, p=p->pre;
if(!p){
np->pre = root;
}else{
node *q = p->p[w];
if(p->len+1 == q->len){
np->pre = q;
}else{
node *nnd = ecnt++;
memcpy(nnd->p, q->p, sizeof (nnd->p));
nnd->len = p->len+1; nnd->pre = q->pre; q->pre = nnd; np->pre = nnd;
while(p&&p->p[w]==q)
p->p[w]=nnd, p=p->pre;
}
}
last = np;
}
const int MAXT = 1000;
char s1[MAXT+10], s2[MAXT+10];
int main(){
int ans = 0, len = 0;
scanf("%s %s", s1, s2);
int len1 = strlen(s1);
int len2 = strlen(s2);
for(int i=0;i<len1;i++)
Insert(s1[i]-'a');
node *p = root;
for(int j=0;j<len2;j++){
int now = s2[j]-'a';
if(p->p[now])
p = p->p[now], len++;
else{
while(p&&!p->p[now])
p = p->pre;
if(!p)
len=0, p = root;
else
len=p->len+1, p=p->p[now];
}
ans = max(len, ans);
}
printf("%d\n", ans);
return 0;
}