1. 程式人生 > >【刷題】SPOJ 1811 LCS - Longest Common Substring

【刷題】SPOJ 1811 LCS - Longest Common Substring

gis con register 很多 more line turn mem AR

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

Solution

做字符串題根SPOJ打交道很多啊
SAM模板,並get新技能,一個串的SAM與另一個串的匹配
將一個串的SAM建好之後,枚舉另一個串的字符,如果可以直接匹配就直接匹配,如果直接匹配不了,那麽將SAM的指針不停地往上跳,使得代表字符串的長度越來越小,以便能夠匹配

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long const int MAXN=250000+10; int n1,n2,tot=1,las=1,ch[MAXN<<1][30],len[MAXN<<1],fa[MAXN<<1],size[MAXN<<1],ans; char s1[MAXN],s2[MAXN]; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char ch='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch); } template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void extend(int c) { int p=las,np=++tot; las=np; len[np]=len[p]+1; while(p&&!ch[p][c])ch[p][c]=np,p=fa[p]; if(!p)fa[np]=1; else { int q=ch[p][c]; if(len[q]==len[p]+1)fa[np]=q; else { int nq=++tot; fa[nq]=fa[q]; memcpy(ch[nq],ch[q],sizeof(ch[nq])); len[nq]=len[p]+1; fa[np]=fa[q]=nq; while(p&&ch[p][c]==q)ch[p][c]=nq,p=fa[p]; } } size[np]=1; } int main() { scanf("%s%s",s1+1,s2+1); n1=strlen(s1+1),n2=strlen(s2+1); for(register int i=1;i<=n1;++i)extend(s1[i]-'a'+1); for(register int i=1,j=1,res=0,c;i<=n2;++i) { c=s2[i]-'a'+1; if(ch[j][c])res++,j=ch[j][c]; else { while(j&&!ch[j][c])j=fa[j]; if(!j)res=0,j=1; else res=len[j]+1,j=ch[j][c]; } chkmax(ans,res); } write(ans,'\n'); return 0; }

【刷題】SPOJ 1811 LCS - Longest Common Substring