bzoj 2946: [Poi2000]公共串 (后缀自动机)
2016-12-20 18:47
369 查看
2946: [Poi2000]公共串
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 783 Solved: 340
[Submit][Status][Discuss]
Description
给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l 读入单词
l 计算最长公共子串的长度
l 输出结果
Input
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
Output
仅一行,一个整数,最长公共子串的长度。Sample Input
3abcb
bca
acbc
Sample Output
2HINT
Source
[Submit][Status][Discuss]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 20000
using namespace std;
int n,m,cnt,last,root,p,q,np,nq,len;
int fa
,ch
[30],l
,a
,cl
,mn
,ans,pos
,v
;
char s
;
void extend(int x)
{
int c=a[x];
p=last; np=++cnt; last=np;
l[np]=x;
for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if (!p) fa[np]=root;
else {
int q=ch[p][c];
if (l[q]==l[p]+1) fa[np]=q;
else {
nq=++cnt; l[nq]=l[p]+1;
memcpy(ch[nq],ch[q],sizeof ch[nq]);
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for (;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
}
void solve()
{
int tmp=0; p=1;
memset(cl,0,sizeof(cl));
for (int i=1;i<=len;i++){
int c=s[i]-'a';
if (ch[p][c]) p=ch[p][c],tmp++;
else {
while (p&&!ch[p][c]) p=fa[p];
if (!p) p=root,tmp=0;
else tmp=l[p]+1,p=ch[p][c];
}
cl[p]=max(cl[p],tmp);
}
for (int i=cnt;i>=1;i--){
int t=pos[i];
mn[t]=min(mn[t],cl[t]);
if (fa[t]&&cl[t]) cl[fa[t]]=l[fa[t]];
}
}
int main()
{
freopen("a.in","r",stdin);
freopen("my.out","w",stdout);
scanf("%d",&n);
last=root=++cnt;
memset(mn,127,sizeof(mn));
scanf("%s",s+1); len=strlen(s+1);
for (int i=1;i<=len;i++) a[i]=s[i]-'a',extend(i);
if (n==1) {
printf("%d\n",len);
return 0;
}
for (int i=1;i<=cnt;i++) v[l[i]]++;
for (int i=1;i<=len;i++) v[i]+=v[i-1];
for (int i=1;i<=cnt;i++) pos[v[l[i]]--]=i;
for (int i=2;i<=n;i++) {
scanf("%s",s+1); len=strlen(s+1);
solve();
}
for (int i=1;i<=cnt;i++) ans=max(ans,mn[i]);
printf("%d\n",ans);
}
相关文章推荐
- BZOJ 2946 [Poi2000]公共串 后缀自动机
- bzoj 2946: [Poi2000]公共串 后缀自动机
- [BZOJ2946][Poi2000]公共串(后缀自动机)
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
- [BZOJ2946][POI2000]公共串(后缀自动机)
- [BZOJ2946][Poi2000]公共串 后缀自动机
- 后缀自动机 模板 【Poi2000】 公共串 bzoj 2946
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
- 【bzoj2946】[Poi2000]公共串 后缀自动机
- [BZOJ2946][Poi2000]公共串 && 后缀自动机
- bzoj2946 [Poi2000]公共串(后缀数组 || 后缀自动机)
- bzoj 2946: [Poi2000]公共串 后缀自动机
- 2946: [Poi2000]公共串 后缀自动机
- 【BZOJ 2946】【POI 2000】公共串【后缀数组】【裸】
- BZOJ 2946: [Poi2000]公共串 后缀数组
- 2946: [Poi2000]公共串 后缀自动机
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
- [bzoj2946][后缀数组][Poi2000]公共串
- [BZOJ2946][Poi2000]公共串解题报告|后缀自动机
- [后缀自动机 模板题] SPOJ 1812 Longest Common Substring II & BZOJ 2946 [Poi2000]公共串