3160 最长公共子串

时间限制: 2 s

空间限制: 128000 KB

题目等级 : 大师 Master

题目描述 Description

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

输入描述 Input Description

读入两个字符串

输出描述 Output Description

输出最长公共子串的长度

样例输入 Sample Input

yeshowmuchiloveyoumydearmotherreallyicannotbelieveit

yeaphowmuchiloveyoumydearmother

样例输出 Sample Output

27

数据范围及提示 Data Size & Hint

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

分类标签 Tags

后缀树 后缀树组 树结构

/*
后缀数组求lcp裸题.
先用无关字符将两个串连接起来.
然后用后缀数组求一下rank.
这样答案显然就是两个相邻rank后缀的最大前缀.
这样的话.
求出height数组,
然后找一个i和i-1分别属于前后两个串就可以了.
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 2000010
using namespace std;
int n,sa[MAXN],l1,l2,m=128,rank[MAXN],height[MAXN],t1[MAXN],c[MAXN],t2[MAXN],ans,tot,s[MAXN];
char ch1[MAXN],ch2[MAXN],ch[MAXN];
bool cmp(int *y,int a,int b,int k)
{
int a1=y[a],b1=y[b];
int a2=a+k>=n?-1:y[a+k];
int b2=b+k>=n?-1:y[b+k];
return a1==b1&&a2==b2;
}
void slovesa()
{
int *x=t1,*y=t2;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[i]=s[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
for(int k=1,p=0;k<=n;k<<=1,m=p,p=0)
{
for(int i=n-k;i<n;i++) y[p++]=i;
for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<n;i++) c[x[y[i]]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);p=1;x[sa[0]]=0;
for(int i=1;i<n;i++)
{
if(cmp(y,sa[i-1],sa[i],k)) x[sa[i]]=p-1;
else x[sa[i]]=p++;
}
if(p>=n) break;
}
}
void sloveheight()
{
int k=0;
for(int i=0;i<n;i++) rank[sa[i]]=i;
for(int i=0;i<n;height[rank[i++]]=k)
{
if(!rank[i]) continue;
int j=sa[rank[i]-1];
if(k) k--;
while(j+k<n&&i+k<n&&s[j+k]==s[i+k]) k++;
}
height[0]=0;
}
void sloveans()
{
for(int i=0;i<n;i++)
if(height[i]>ans)
{
if(sa[i]<l1&&sa[i-1]>l1) ans=height[i];
if(sa[i]>l1&&sa[i-1]<l1) ans=height[i];
}
}
int main()
{
scanf("%s",ch1);
scanf("%s",ch2);
l1=strlen(ch1);
l2=strlen(ch2);
for(int i=0;i<l1;i++) s[n++]=ch1[i];
s[n++]='$';
for(int i=0;i<l2;i++) s[n++]=ch2[i];
slovesa(),sloveheight(),sloveans();
printf("%d",ans);
return 0;
}

Codevs 3160 最长公共子串(后缀数组)的更多相关文章

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

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

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

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

  3. poj 2774 最长公共子串 后缀数组

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 25752   Accepted: 10 ...

  4. codevs 3160 最长公共子串

    3160 最长公共子串 http://codevs.cn/problem/3160/  时间限制: 2 s  空间限制: 128000 KB   题目描述 Description 给出两个由小写字母组 ...

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

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

  6. POJ 2774 Long Long Message [ 最长公共子串 后缀数组]

    题目:http://poj.org/problem?id=2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total ...

  7. 【codevs3160】最长公共子串 后缀数组

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

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

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

  9. poj 1743 Musical Theme(最长重复子串 后缀数组)

    poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...

随机推荐

  1. 精确选择识别png图片有像素的区域(使用方法)

    /** * * *---------------------------------------* * | ***精确选择识别png图片有像素的区域*** | * *----------------- ...

  2. CCF 2016-12-1 最大波动

    CCF 2016-12-1 最大波动 题目 问题描述 小明正在利用股票的波动程度来研究股票.小明拿到了一只股票每天收盘时的价格,他想知道,这只股票连续几天的最大波动值是多少,即在这几天中某天收盘价格与 ...

  3. Linux中shell字符串分隔、字符串替换、字符串拼接

    1.从properties文件中读取变量 SERVER_NAME=`sed '/project.config/!d;s/.*=//' conf/dubbo.properties | tr -d '\r ...

  4. matlab安装与使用

    Matlab安装和使用 百度网盘连接:https://pan.baidu.com/s/1aHPeAkNofCuwyYopnva4Mg 提取码:ci96 下载完成后: 将R2017b_win64_dvd ...

  5. Thomas Brinkhoff 基于路网的移动对象生成器的使用[第二版]

    Thomas Brinkhoff 基于路网的移动对象生成器的使用 Thomas Brinkhoff 基于路网的移动对象生成器的使用 相关操作的说明 相关文件的说明 运行 导入eclipse后运行时选择 ...

  6. spring boot打包,依赖、配置文件分离,拷贝启动脚本

    一.最终打包的目录结构 二.项目结构 三.开始 1.最终打包的目录,可根据自己需要修改. <properties> <mzservice.path>${project.buil ...

  7. Python小列子-读取照片位置

    Python exifread Python利用exifread库来解析照片的经纬度,对接百度地图API显示拍摄地点. import exifread import re import json im ...

  8. 【转载】C#中string.IsNullOrEmpty和string.IsNullOrWhiteSpace区别

    在C#中判断字段是否为空或者Null的时候,我们一般会使用到string.IsNullOrEmpty和string.IsNullOrWhiteSpace方法,这两个方法在大部分情况下判断的结果是一致的 ...

  9. Java内存模型JMM简单分析

    参考博文:http://blog.csdn.net/suifeng3051/article/details/52611310 http://www.cnblogs.com/nexiyi/p/java_ ...

  10. HTTP协议复习三--TCP/IP的网络分层模型和OSI 网络分层模型

    TCP/IP网络分层模型 第一层叫“链接层”(link layer),负责在以太网.WiFi这样的底层网络上发送原始数据包,工 作在网卡这个层次,使用MAC地址来标记网络上的设备,所以有时候也叫MAC ...