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

  1. banana
  2. cianaic

Sample Output

  1. 3
  2.  
  3. 题目大意:给两个字符串,求最长的公共子串的长度。
    题目分析:扫一遍height数组即可。
  4.  
  5. 代码如下:
  1. # include<iostream>
  2. # include<cstdio>
  3. # include<queue>
  4. # include<cmath>
  5. # include<string>
  6. # include<cstring>
  7. # include<algorithm>
  8. using namespace std;
  9.  
  10. const int N=100000;
  11.  
  12. int SA[N*2+5];
  13. int cnt[N*2+5];
  14. int rk[N*2+5];
  15. int tSA[N*2+5];
  16. int height[N*2+5];
  17. int n;
  18. string str;
  19.  
  20. bool same(int i,int j,int k)
  21. {
  22. if(tSA[i]!=tSA[j]) return false;
  23. if(i+k>=n&&j+k<n) return false;
  24. if(i+k<n&&j+k>=n) return false;
  25. return tSA[i+k]==tSA[j+k];
  26. }
  27.  
  28. void buildSA(string s)
  29. {
  30. int m=27;
  31. n=s.size();
  32. for(int i=0;i<m;++i) cnt[i]=0;
  33. for(int i=0;i<n;++i) ++cnt[rk[i]=s[i]-'a'];
  34. for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
  35. for(int i=n-1;i>=0;--i) SA[--cnt[rk[i]]]=i;
  36. for(int k=1;k<=n;k<<=1){
  37. int p=0;
  38. for(int i=n-k;i<n;++i) tSA[p++]=i;
  39. for(int i=0;i<n;++i) if(SA[i]>=k) tSA[p++]=SA[i]-k;
  40.  
  41. for(int i=0;i<m;++i) cnt[i]=0;
  42. for(int i=0;i<n;++i) ++cnt[rk[tSA[i]]];
  43. for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
  44. for(int i=n-1;i>=0;--i) SA[--cnt[rk[tSA[i]]]]=tSA[i];
  45.  
  46. swap(rk,tSA);
  47. p=1;
  48. rk[SA[0]]=0;
  49. for(int i=1;i<n;++i)
  50. rk[SA[i]]=same(SA[i],SA[i-1],k)?p-1:p++;
  51. if(p>=n) break;
  52. m=p;
  53. }
  54. }
  55.  
  56. void getHeight()
  57. {
  58. for(int i=0;i<n;++i) rk[SA[i]]=i;
  59. int k=0;
  60. for(int i=0;i<n;++i){
  61. if(rk[i]==0){
  62. height[rk[i]]=k=0;
  63. }else{
  64. if(k) --k;
  65. int j=SA[rk[i]-1];
  66. while(i+k<n&&j+k<n&&str[i+k]==str[j+k]) ++k;
  67. height[rk[i]]=k;
  68. }
  69. }
  70. }
  71.  
  72. string str1,str2;
  73.  
  74. bool diff(int i,int j,int m)
  75. {
  76. if(SA[i]==m||SA[j]==m) return false;
  77. return (SA[i]-m)/abs(SA[i]-m)*(SA[j]-m)/abs(SA[j]-m)<0;
  78. }
  79.  
  80. int f(int m)
  81. {
  82. int ans=0;
  83. for(int i=1;i<n;++i){
  84. if(diff(i,i-1,m)&&height[i]>ans)
  85. ans=height[i];
  86. }
  87. return ans;
  88. }
  89.  
  90. int main()
  91. {
  92. while(cin>>str1>>str2)
  93. {
  94. str=str1+(char)('z'+1)+str2;
  95. buildSA(str);
  96. getHeight();
  97. //cout<<"here is good"<<endl;
  98. printf("%d\n",f(str1.size()));
  99. }
  100. return 0;
  101. }

  


HDU 1403-Longest Common Substring (后缀数组)的更多相关文章

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

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

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

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

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

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

  4. HDU - 1403 - Longest Common Substring

    先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

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

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

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

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

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

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

  8. spoj 1811 LCS - Longest Common Substring (后缀自己主动机)

    spoj 1811 LCS - Longest Common Substring 题意: 给出两个串S, T, 求最长公共子串. 限制: |S|, |T| <= 1e5 思路: dp O(n^2 ...

  9. SPOJ1811 LCS - Longest Common Substring(后缀自动机)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  10. hdu_1403_Longest Common Substring(后缀数组的应用)

    题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...

随机推荐

  1. 005-Scala数组操作实战详解

    005-Scala数组操作实战详解 Worksheet的使用 交互式命令执行平台 记得每次要保存才会出相应的结果 数组的基本操作 数组的下标是从0开始和Tuple不同 缓冲数组ArrayBuffer( ...

  2. eap-md5

    eap-md5       文件路径 用途 示例 备注 #gedit /usr/local/etc/raddb/sites-available/default #gedit /usr/local/et ...

  3. 重置了下系统好多关于mysql密码的文章都很渣拷分好的备用

    方法1: 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass ...

  4. IOS开发:监听来电状态的改变。

    #import <CoreTelephony/CTCallCenter.h> #import <CoreTelephony/CTCall.h> @property(nonato ...

  5. Android数据库 — — —查询数据

    package com.example.datebasetest; import android.content.ContentValues;import android.database.Curso ...

  6. Android 与Unity交互之Toast消息

    Toast.makeText(MainActivity.this,message.obj.toString(),Toast.LENGTH_SHORT).show();这一句代码不能直接放在 publi ...

  7. Android系统启动过程

    首先Android框架架构图: Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用. 启动的过程如下图所示:(图片来自网上,后面有地址)   下面将从And ...

  8. windows核心编程---第九章 同步设备IO与异步设备IO之同步IO

    同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...

  9. 如何消除inline-block元素间间距问题(转)

    一.现象描述    真正意义上的inline-block水平呈现的元素间,换行显示或空格分隔的情况下会有间距,很简单的个例子: <input /> <input type=" ...

  10. WPF(WP7、WP8)实现圆形图片

    在WP平台上制作图片圆角其实特别简单, 用Image控件的Clip属性即可(RadiusX-Y设置为图片尺寸的一半) <Image Source="{Binding photo}&qu ...