先上题目:

Longest Common Substring

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4010    Accepted Submission(s): 1510

Problem Description
Given two strings, you have to tell the length of the Longest Common Substring of them.

For example:
str1 = banana
str2 = cianaic

So the Longest Common Substring is "ana", and the length is 3.

 
Input
The input contains several test cases. Each test case contains two strings, each string will have at most 100000 characters. All the characters are in lower-case.

Process to the end of file.

 
Output
For each test case, you have to tell the length of the Longest Common Substring of them.
 
Sample Input
banana
cianaic
 
Sample Output
3
 
  题意:给出两个串,问你这两个串的最长公共子串的长度是多少。
  后缀数组入门题。首先,不得不承认,现在我的水平只可以套一下模板,通过模板我们可以求出sa[],rank[],height[]三个数组。
  对于这里的字符串,我们是从0~n-1。
  sa[i]指的是字典序排第i的后缀的下标是什么,rank[i]指的是原串中第i个后缀(就是从第i个字符开始到末尾的字符串)在后缀数组中排第几。height[i]表示后缀数组中第i个后缀和第i-1一个后缀的最长公共前缀的长度是多少(其中height[0]=0)。
  这里的做法是首先将两个字符串连接起来,在连接处加一个连接符(没在这两个字符串中出现过的字符即可),然后求出height[],再扫描height[],寻找某个同时符合以下要求的值:①比最大值还要大,②suffex(sa[i])和suffex(sa[i-1])分属于两个不同的字符串。这里需要注意每个数组的长度足够。
 
上代码:
 
 #include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 100002
using namespace std; char s[(MAX<<)],b[MAX];
int sa[MAX<<],rank[MAX<<],height[MAX<<],t[MAX<<],t2[MAX<<],c[MAX<<],n,li;
int f[(MAX<<)]; void build_sa(int m){
int i,*x=t,*y=t2;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[i]=s[i]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[i]]]=i;
for(int k=;k<=n;k<<=){
int p=;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[y[i]]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=; x[sa[]]=;
for(i=;i<n;i++){
x[sa[i]]=y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k] ? p- : p++;
}
if(p>=n) break;
m=p;
}
for(i=;i<n;i++) rank[sa[i]]=i;
} void getHeight(){
int i,j,k=;
for(i=;i<n;i++){
if(k) k--;
j=sa[rank[i]-];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
} int main()
{
int maxn;
//freopen("data.txt","r",stdin);
while(scanf("%s %s",s,b)!=EOF){
strcat(s,"&");
li=strlen(s);
for(int i=;i<li-;i++) f[i]=;
strcat(s,b);
f[li-]=;
n=strlen(s);
for(int i=li;i<n;i++) f[i]=-;
build_sa();
getHeight();
maxn=;
for(int i=;i<n;i++){
if(maxn<height[i] && f[sa[i-]]*f[sa[i]]<){
maxn=height[i];
}
}
printf("%d\n",maxn);
}
return ;
}

/*1403*/

HDU - 1403 - Longest Common Substring的更多相关文章

  1. hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=1403 Longest Common Substring Time Limit: 8000/4000 MS (Ja ...

  2. HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)

    Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...

  3. HDU 1403 Longest Common Substring(最长公共子串)

    http://acm.hdu.edu.cn/showproblem.php?pid=1403 题意:给出两个字符串,求最长公共子串的长度. 思路: 刚开始学后缀数组,确实感觉很难,但是这东西很强大,所 ...

  4. HDU 1403 Longest Common Substring(后缀数组,最长公共子串)

    hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小 ...

  5. POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203

    后缀数组的买1送2题... HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA..原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1....不懂可以去看罗大神的论文... 就 ...

  6. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

  7. 【HDOJ】1403 Longest Common Substring

    后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXM 28 ...

  8. hdu1403 Longest Common Substring

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=1403 题目: Longest Common Substring Time Limit: 800 ...

  9. SPOJ LCS2 - Longest Common Substring II

    LCS2 - Longest Common Substring II A string is finite sequence of characters over a non-empty finite ...

随机推荐

  1. 虚拟化技术概要之VMM结构

    1. 概述 当前主流的 VMM (Virtual Machine Monitor) 实现结构可以分为三类: 宿主模型 (OS-hosted VMMs)Hypervisor 模型 (Hypervisor ...

  2. JAVA基础(多线程Thread和Runnable的使用区别(转载)

    转自:http://jinguo.iteye.com/blog/286772 Runnable是Thread的接口,在大多数情况下“推荐用接口的方式”生成线程,因为接口可以实现多继承,况且Runnab ...

  3. PCB Genesis脚本 C#调用Javascript

    曾经用node.js测试写Genesis脚本失败了,这次借助开发PCB规则引擎的机会(基于JS V8引擎与.net深度交互性), 验证一下Javascript是否可用于写Genesis脚本. 一.测试 ...

  4. go多进程

    package main import "fmt" import "time"func loop() { for i := 0; i < 10; i++ ...

  5. nodejs在windows下的安装

    Windowv 上安装Node.js Windows 安装包(.msi) : 32 位安装包下载地址 : http://nodejs.org/dist/v0.10.26/node-v0.10.26-x ...

  6. P3199 [HNOI2009]最小圈

    传送门 据rqy说有这么一个结论\[ans=\min_{v \in V,F_n(v)\neq \infty} \max_{0 \leq k \leq n - 1} \left[\frac{F_n(v) ...

  7. 面向对象之继承-5种JavaScript继承的方法

    今天我们讨论一下常用的几种继承方法:首先我们创建一个动物函数Animal: function Animal () { this.species = '动物' }再写准备名叫猫咪的函数Cat: func ...

  8. centos6.6安装redis

    .安装仓库 yum install epel-release -y2.安装redis yum install redis -y3.程序文件说明 安装完毕后有以下几个文件位于/usr/bin目录: re ...

  9. day02_12/12/2016_bean的实例化之静态工厂方式

  10. Java系列学习(十)-包与权限修饰符

    1.形式参数和返回值的问题 (1)形式参数: A:类名:需要该类的对象 B:抽象类名:需要改类的子类对象 C:接口名:需要该接口的实现对象 (2)返回值类型: A:类名:抽象类名:返回的是该类的对象 ...