codevs 3160 最长公共子串(SAM)
2016-02-18 20:21
501 查看
3160 最长公共子串
题目描述 Description给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
输入描述 Input Description
读入两个字符串
输出描述 Output Description
输出最长公共子串的长度
样例输入 Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
样例输出 Sample Output
27
数据范围及提示 Data Size & Hint
单个字符串的长度不超过100000
【思路】
SAM求LCS
【代码】
#include<cstdio> #include<cstring> using namespace std; const int N = 2*1e5+10; char s ; int sz,root,last,fa ,ch [26],l ,n; void add(int x) { int c=s[x]-'a'; int p=last,np=++sz; last=np; l[np]=x+1; 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[p]+1==l[q]) fa[np]=q; else { int nq=++sz; l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); fa[nq]=fa[q]; fa[np]=fa[q]=nq; for(;p&&q==ch[p][c];p=fa[p]) ch[p][c]=nq; } } } void build() { root=last=++sz; scanf("%s",s); n=strlen(s); for(int i=0;i<n;i++) add(i); } void lcs() { scanf("%s",s); n=strlen(s); int p=root,ans=0,len=0; for(int i=0;i<n;i++) { int c=s[i]-'a'; if(ch[p][c]) { len++; p=ch[p][c]; } else { for(;p&&!ch[p][c];p=fa[p]); if(!p) { p=root; len=0; } else { len=l[p]+1; p=ch[p][c]; } } if(len>ans) ans=len; } printf("%d",ans); } int main() { build(); lcs(); return 0; }
相关文章推荐
- 20160218自学Linux_根文件目录介绍+目录管理命令学习(mkdir,rmdir,tree,touch,stat,rm,nano,cp,mv,insatll)
- nefu269 noip2006能量项链【区间dp 环】
- Android防止内存泄露
- NOIP组模拟2016.2.18
- 机器人开发--服务准备
- 《linux优化之需要开机启动的重点服务详解》
- CDQ分治题目泛做(WYD第二轮)
- 发现,思索,反思
- 笔记:harvesting discriminative meta objects with deep CNN features for scene classification
- IBM DS3500系列存储SAS升级FC记
- Mysql索引会失效的几种情况分析
- JavaScript中关于数值转换的问题
- 关于AJAX的跨域问题
- 寒假作业(4)
- mmap设备操作
- 大教堂与集市(The Cathedral and the Bazaar)读书笔记
- ( 转 )Github配置
- 寒假作业(3)
- Android实现欢迎界面的自动跳转
- linux系统管理及配置