LCS2 - Longest Common Substring II
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 a bit harder, for some 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 at most 10 lines, each line consists of no more than 100000 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 aaaajfaaaa Output: 2
之前用kmp写过类似的题,估计这个铁定超,,
在一个串上建sam,然后开始扫,lcs表示当前串匹配到这个结点时和sam上串的最大公共子串长度,nlcs表示前n个的
ac代码
#include<stdio.h> #include<stdlib.h> #include<string.h> #define max(a,b) (a>b?a:b) #define N 300010 struct sam { sam *pre,*son[26]; int len,lcs,nlcs; }que[N],*root,*tail,*b[N]; int tot; void add(int c,int l) { sam *p=tail,*np=&que[tot++]; np->len=np->nlcs=l; tail=np; while(p&&p->son[c]==NULL) { p->son[c]=np; p=p->pre; } if(p==NULL) np->pre=root; else { sam *q=p->son[c]; if(p->len+1==q->len) np->pre=q; else { sam *nq=&que[tot++]; *nq=*q; nq->len=nq->nlcs=p->len+1; np->pre=q->pre=nq; while(p&&p->son[c]==q) { p->son[c]=nq; p=p->pre; } } } } char str[N>>1]; int cnt[N>>1],len; void build() { int i,j; root=tail=&que[tot++]; for(i=0;i<len;i++) add(str[i]-'a',i+1); memset(cnt,0,sizeof(cnt)); for(i=0;i<tot;i++) cnt[que[i].len]++; for(i=1;i<=len;i++) cnt[i]+=cnt[i-1]; for(i=0;i<tot;i++) b[--cnt[que[i].len]]=&que[i]; } int main() { int i; scanf("%s",str); len=strlen(str); build(); while(scanf("%s",str)!=EOF) { sam *p=root; int l=0,i; for(i=0;str[i];i++) { int now=str[i]-'a'; if(p->son[now]) { l++; p=p->son[now]; } else { while(p&&p->son[now]==NULL) { p=p->pre; } if(p==NULL) { l=0; p=root; } else { l=p->len+1; p=p->son[now]; } } if(l>p->lcs) p->lcs=l; } for(i=tot-1;i>=0;i--) { p=b[i]; if(p->lcs<p->nlcs) p->nlcs=p->lcs; if(p->pre&&p->pre->lcs<p->lcs) p->pre->lcs=p->lcs; p->lcs=0; } } int ans=0; for(i=0;i<tot;i++) { if(que[i].nlcs>ans) ans=que[i].nlcs; } printf("%d\n",ans); }