codevs 3160 最长公共子串
给出两个由小写字母组成的字符串,求它们的最长公共子串的长度。
读入两个字符串
输出最长公共子串的长度
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit
yeaphowmuchiloveyoumydearmother
27
单个字符串的长度不超过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 最长公共子串的更多相关文章
- codevs 3160 最长公共子串(SAM)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...
- Codevs 3160 最长公共子串(后缀数组)
3160 最长公共子串 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长 ...
- codevs 3160 最长公共子串 后缀自动机
http://codevs.cn/problem/3160/ 后缀自动机板子题,匹配的时候要注意如果到一个点失配向前匹配到一个点时,此时的tmp(当前匹配值)为t[j].len+1而不是t[t[j]. ...
- CODE【VS】3160 最长公共子串 (后缀自动机)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- CODE【VS】 3160 最长公共子串 (后缀数组)
3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...
- 【wikioi】3160 最长公共子串(后缀自动机)
http://codevs.cn/problem/3160/ sam的裸题...(之前写了spoj上另一题sam的题目,但是spoj被卡评测现在还没评测完QAQ打算写那题题解时再来详细介绍sam的.. ...
- Codevs 1425 最长公共子串
1425 最长公共子串 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 题目描述 Description 输入N(2<=N<= ...
- codevs 2185 最长公共上升子序列
题目链接: codevs 2185 最长公共上升子序列codevs 1408 最长公共子序列 题目描述 Description熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
随机推荐
- Leetcode题库——7.反转整数
@author: ZZQ @software: PyCharm @file: IntReverse.py @time: 2018/9/16 16:36 要求:整数反转(给定一个 32 位有符号整数,将 ...
- BNUOJ 52303 Floyd-Warshall Lca+bfs最短路
题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52303 Floyd-Warshall Time Limit: 60000msMemory L ...
- sprint冲刺(第二天)
今天的每日立会是在早上早餐后8点在宿舍讨论的,大概讨论了关于四则运算练习器APP的看法,也对一些较为基础的功能进行说明
- 结对&团队之1715|K班取经
声明:同学请勿抄袭,追责莫要怪我: 因为暂时闲着没事,就翻阅学长学姐的博客找找灵感,个人觉得应该还有人和我一样对软工实践未来的一大段路还很天真,包括目前的结对作业和团队组队也很迷路,于是写下这篇博客提 ...
- jquery easyui datagrid getSelected getChecked获取选择行数据(勾选)数据
要想获得上图所选取的元素只能用getChecked getSelected不能进行多个选择,只能单选 /* getSelected取得选中的数据,否则为null */ var user=$(" ...
- implement min heap
class MinHeap{ private ArrayList<Integer> arr; private int DEFAULT_LEN = 10; public MinHeap(){ ...
- 这个网页用到了什么技术,<script>标签,还有双大括号{{}}是什么意思
<#compress> <@override name="title">${brand.name}-商品</@override> <@ov ...
- BZOJ 3357: [Usaco2004]等差数列
3357: [Usaco2004]等差数列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 338 Solved: 160[Submit][Statu ...
- BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题
BZOJ 1031 [JSOI2007]字符加密Cipher | 后缀数组模板题 将字符串复制一遍接在原串后面,然后后缀排序即可. #include <cmath> #include &l ...
- 51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径
51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径 题面 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即 ...