SPOJ 1811 Longest Common Substring(后缀自动机模板题)
Longest Common Substring
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: 3
求两个字符串的最大公共子串的长度
代码如下:
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; const int N=250005; struct State { State *link,*go[26]; int step; void clear() { link=0; step=0; memset(go,0,sizeof(go)); } }*root,*last; State statePool[N*2],*cur; void init() { cur=statePool; root=last=cur++; root->clear(); } void Insert(int w) { State *p=last; State *np=cur++; np->clear(); np->step=p->step+1; while(p&&!p->go[w]) p->go[w]=np,p=p->link; if(p==0) np->link=root; else { State *q=p->go[w]; if(p->step+1==q->step) np->link=q; else { State *nq=cur++; nq->clear(); memcpy(nq->go,q->go,sizeof(q->go)); nq->step=p->step+1; nq->link=q->link; q->link=nq; np->link=nq; while(p&&p->go[w]==q) p->go[w]=nq, p=p->link; } } last=np; } char A[N],B[N]; int main() { int maxx,len; while(scanf("%s%s",A,B)!=EOF) { len=0; maxx=0; int n,m; n=strlen(A); m=strlen(B); init(); State *p=root; for(int i=0;i<n;i++) Insert(A[i]-'a'); for(int i=0;i<m;i++) { if(p->go[B[i]-'a']) { len++; p=p->go[B[i]-'a']; } else { while(p&&!p->go[B[i]-'a'])p=p->link; if(!p) { p=root; len=0; } else { len=p->step+1; p=p->go[B[i]-'a']; } } maxx=max(maxx,len); } cout<<maxx<<endl; } return 0; }