[bzoj2946]公共串
2018-02-27 20:48
169 查看
题目
给出几个由小写字母构成的单词,求它们最长的公共子串的长度。任务:
l 读入单词
l 计算最长公共子串的长度
l 输出结果
分析
对第一个字符串建后缀自动机对于每一个状态维护f[i]表示所有串与该状态匹配的公共最长长度。
对于其他的字符串,都在后缀自动机上进行匹配。
并每次都计算g[i]表示该字符串与状态i匹配的最大长度。
每次跑完后,要逆推补全g的值。
对于状态i,若g[i]>0,则g[pre[i]]=step[pre[i]]。因为i成功被匹配了,匹配长度>step[pre[i]],pre[i]也被匹配了,匹配长度为step[pre[i]]。
做完后用g和f取min更新f。
最后在f中取最大值。
code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define N 5005 #define LL long long using namespace std; int n; int len[N*2]; int ch[N*2][30],fail[N*2]; int f[N*2],w[N*2],b[N*2],c[N*2]; int last,root,cnt; char s ; void ins(int x) { int p,q,np,nq; p=last; last=np=++cnt; len[np]=len[p]+1; w[np]=f[np]=1; for (;!ch[p][x]&&p;p=fail[p]) ch[p][x]=np; if (p==0) fail[np]=root; else { q=ch[p][x]; if (len[q]==(len[p]+1)) fail[np]=q; else { nq=++cnt; len[nq]=len[p]+1; for (int i=0;i<=26;i++) ch[nq][i]=ch[q][i]; fail[nq]=fail[q]; fail[q]=fail[np]=nq; for (;ch[p][x]==q;p=fail[p]) ch[p][x]=nq; } } } int main() { int L=0; scanf("%d",&L); scanf("%s",s+1); n=strlen(s+1); last=cnt=root=1; for (int i=1;i<=n;i++) ins(s[i]-'a'); for (int i=1;i<=cnt;i++) f[i]=len[i]; L--; while (L--) { memset(b,0,sizeof(b)); scanf("%s",s+1); n=strlen(s+1); int p=1,t=0; for (int i=1;i<=n;i++) { int x=s[i]-'a'; while (p!=1&&!ch[p][x]) p=fail[p]; if (!ch[p][x]) t=0; else t=min(t,len[p])+1; if (ch[p][x]) p=ch[p][x]; b[p]=max(b[p],t); } for (int i=cnt;i>=1;i--) { if (b[i]) b[fail[i]]=len[fail[i]]; } for (int i=1;i<=cnt;i++) f[i]=min(f[i],b[i]); } int ans=0; for (int i=1;i<=cnt;i++) { ans=max(ans,f[i]); } printf("%d",ans); return 0; }
相关文章推荐
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
- 【BZOJ2946】[Poi2000]公共串 后缀数组+二分
- bzoj 2946: [Poi2000]公共串 后缀自动机
- 【BZOJ2946】公共串 [SAM]
- bzoj2946 [Poi2000]公共串
- BZOJ2946 [Poi2000]公共串 二分+hash
- BZOJ 2946 Poi2000 公共串 后缀自动机
- 【bzoj2946】[Poi2000]公共串 后缀数组+二分
- 【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】
- BZOJ2946: [Poi2000]公共串
- 【BZOJ2946】公共串(后缀数组)
- BZOJ 2946 [Poi2000]公共串 ——后缀自动机
- bzoj2946 [Poi2000]公共串
- 【BZOJ2946】公共串(后缀数组)
- [BZOJ2946][Poi2000]公共串 && 后缀自动机
- 【BZOJ 2946】[Poi2000]公共串 后缀数组
- 【POI2000】【BZOJ2946】公共串
- [BZOJ 2946]公共串
- BZOJ2946: [Poi2000]公共串
- 【bzoj 2946】公共串(后缀自动机)