3160 最长公共子串

http://codevs.cn/problem/3160/

 时间限制: 2 s
 空间限制: 128000 KB
 
题目描述 Description

给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。

 
输入描述 Input Description

读入两个字符串

 
输出描述 Output Description

输出最长公共子串的长度

 
样例输入 Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
 
样例输出 Sample Output

27

 
数据范围及提示 Data Size & Hint

单个字符串的长度不超过100000

将两个字符串中间用未出现过的字符连接起来

后缀数组

将后缀按rank排序求出height数组

然后枚举i height数组,如果sa[i]和sa[i-1]分别位于连接字符的两侧,则ans=max(ans,height[i])

看后缀数组戳这里http://www.cnblogs.com/TheRoadToTheGold/p/6591534.html

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
using namespace std;
int n,p,q=,k,a[*N],rk[][N*],sa[][N*],h[N*],v[N*],ans;
char s1[N*],s2[N];
int len1,len2;
void mul(int *sa,int *rk,int *SA,int *RK)
{
for(int i=;i<=n;i++) v[rk[sa[i]]]=i;
for(int i=n;i;i--) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+;i<=n;i++) SA[v[rk[i]]--]=i;
for(int i=;i<=n;i++) RK[SA[i]]=RK[SA[i-]]+(rk[SA[i]]!=rk[SA[i-]]||rk[SA[i]+k]!=rk[SA[i-]+k]);
}
void presa()
{
for(int i=;i<=n;i++) v[a[i]]++;
for(int i=;i<=;i++) v[i]+=v[i-];
for(int i=;i<=n;i++) sa[p][v[a[i]]--]=i;
for(int i=;i<=n;i++) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(a[sa[p][i]]!=a[sa[p][i-]]);for(k=;k<n;k<<=,swap(p,q))
{
mul(sa[p],rk[p],sa[q],rk[q]);
if(rk[q][sa[q][n]]==n)
{
swap(p,q);
return;
}
}
}
void getheight()
{
int j;
for(int i=,g=;i<=n;i++)
{
/*if(rk[p][i]==1) 有没有无所谓 因为h[1]不参与计算
{
h[rk[p][i]]=0;
continue;
}*/
j=sa[p][rk[p][i]-];
while(a[i+g]==a[j+g]) g++;
h[rk[p][i]]=g; if(g) g--;
}
}
void solve()
{
int t1,t2;
for(int i=;i<=n;i++)
{
t1=sa[p][i];
t2=sa[p][i-];
if((t1>=len1)^(t2>=len1)) ans=max(ans,h[i]);
}
printf("%d",ans);
}
int main()
{
scanf("%s%s",s1+,s2);
len1=strlen(s1+);len2=strlen(s2);
n=len1;
s1[++n]='z'+;
for(int i=;i<len2;i++) s1[++n]=s2[i];
for(int i=;i<=n;i++) a[i]=s1[i]-'a'+;
presa();
getheight();
solve();
}

2个错误:

① 连接字符的选用,这个字符并不能随便选,它关系到presa()中第二重循环的范围

刚开始用的‘$’,但presa()中第二重循环仍到26,错了,

修改为选用ascll码在z后一个的字符

② solve()中,应该两个后缀分列连接字符两侧即可,一开始写的第一个在左侧,第二个在右侧

codevs 3160 最长公共子串的更多相关文章

  1. codevs 3160 最长公共子串(SAM)

    3160 最长公共子串   题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...

  2. Codevs 3160 最长公共子串(后缀数组)

    3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ...

  3. codevs 3160 最长公共子串 后缀自动机

    http://codevs.cn/problem/3160/ 后缀自动机板子题,匹配的时候要注意如果到一个点失配向前匹配到一个点时,此时的tmp(当前匹配值)为t[j].len+1而不是t[t[j]. ...

  4. CODE【VS】3160 最长公共子串 (后缀自动机)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  5. CODE【VS】 3160 最长公共子串 (后缀数组)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  6. 【wikioi】3160 最长公共子串(后缀自动机)

    http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...

  7. Codevs 1425 最长公共子串

    1425 最长公共子串  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Description 输入N(2<=N<= ...

  8. codevs 2185 最长公共上升子序列

    题目链接: codevs 2185 最长公共上升子序列codevs 1408 最长公共子序列 题目描述 Description熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升 ...

  9. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

随机推荐

  1. HDU 3853 LOOPS 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3853 LOOPS Time Limit: 15000/5000 MS (Java/Others)Me ...

  2. 四则运算截图and代码

    1.运行截图 2.代码 #include<stdio.h> #include<stdlib.h> int main() { int i=300; int a=0; while( ...

  3. 更新ubuntu的源

    什么是Ubuntu的软件源? 我们在使用Debian或者Ubuntu的apt-get工具来安装需要的软件时,其实就是从服务器获取需要安装的软件并把它安装在本地计算机的过程.所谓的软件源,就是我们获取软 ...

  4. 累计进度条 PSP 饼图

    累计进度条   PSP   饼图 每周例行报告 本周PSP 类别 任务 开始时间 结束时间 被打断时间 总计工作时间 2016年9月24日 读书 构建之法-6.7章 19:00 20:00 2 58m ...

  5. 【第十周】四则运算GUI

    下载地址:http://pan.baidu.com/s/1hsc9HRm 这次比上次多了一个记录的功能,是用QT里面的qplaintextedit记录显示出做过的题目. 我是直接看的文档,发现窗体,搜 ...

  6. PAT 1042 字符统计

    https://pintia.cn/problem-sets/994805260223102976/problems/994805280817135616 请编写程序,找出一段给定文字中出现最频繁的那 ...

  7. call()方法和apply()方法

    最近又遇到了JacvaScript中的call()方法和apply()方法,而在某些时候这两个方法还确实是十分重要的,那么就让我总结这两个方法的使用和区别吧. 1. 每个函数都包含两个非继承而来的方法 ...

  8. linux使用密文生成os账户

    1.生成账户 [hufangrui@xxx ~]$ openssl passwd -1Password: Verifying - Password: $1$szzkROBZ$GYxffRLp8K5vW ...

  9. MySQL数据库中varchar与char类型的区别

    在数据库中建表时,需要给数据定义一个数据库中的数据库类型,当需要给String类型定义一个数据库中的类型时,可以看见有两个选择,一个是varchar,另一个是char,有很多人不清楚两者的区别,包括自 ...

  10. 微信小程序 功能函数 购物车商品删除

    // 购物车删除 deleteList(e) { const index = e.currentTarget.dataset.index; let carts = this.data.carts; c ...