题意:给出两个字符串,求最长公共子串的长度。

题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)切割,然后两个串的最长公共字串就变成了全部后缀的最长公共前缀。这时就要用到height数组,由于随意两个后缀的公共前缀必然是某些height值中的最小值,而这个值假设最大则一定是height中的最大值。在此题中还要注意height最大一定要在两个值所代表的后缀分属不同的字符串地前提下。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. const int maxn = 200000+1000;
  7.  
  8. struct SuffixArray {
  9. char s[maxn];
  10. int sa[maxn],rank[maxn],height[maxn];
  11. int t1[maxn],t2[maxn],c[maxn],n, m;
  12.  
  13. void init(char *str) {
  14. n = strlen(str);
  15. strcpy(s, str);
  16. m = 256;
  17. }
  18. void build_sa() {
  19. int i,*x=t1,*y=t2;
  20. for(i=0; i<m; i++) c[i]=0;
  21. for(i=0; i<n; i++) c[x[i]=s[i]]++;
  22. for(i=1; i<m; i++) c[i]+=c[i-1];
  23. for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
  24. for(int k=1; k<=n; k<<=1) {
  25. int p=0;
  26. for(i=n-k; i<n; i++) y[p++]=i;
  27. for(i=0; i<n; i++)if(sa[i]>=k) y[p++]=sa[i]-k;
  28. for(i=0; i<m; i++) c[i]=0;
  29. for(i=0; i<n; i++) c[x[y[i]]]++;
  30. for(i=1; i<m; i++) c[i]+=c[i-1];
  31. for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
  32. swap(x,y);
  33. p=1;
  34. x[sa[0]]=0;
  35. for(i=1; i<n; i++)
  36. x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
  37. if(p>=n) break;
  38. m=p;
  39. }
  40. }
  41. void build_height() {
  42. int i,j,k=0;
  43. for(i=0; i<n; i++) rank[sa[i]]=i;
  44. for(i=0; i<n; i++) {
  45. if(k)k--;
  46. j=sa[rank[i]-1];
  47. while(s[i+k]==s[j+k]) k++;
  48. height[rank[i]]=k;
  49. }
  50. }
  51. void solve(int len1) {
  52. int ans=0;
  53. for(int i=2; i<n; i++) {
  54. if(sa[i]<len1 && sa[i-1]>len1
  55. ||sa[i]>len1 && sa[i-1]<len1) {
  56. ans = max(ans, height[i]);
  57. }
  58. }
  59. printf("%d\n", ans);
  60. }
  61. };
  62.  
  63. SuffixArray sa;
  64.  
  65. char str[maxn];
  66.  
  67. int main() {
  68. scanf("%s", str);
  69. int len1 = strlen(str);
  70. str[len1] = 1;
  71. scanf("%s", str + len1 + 1);
  72.  
  73. sa.init(str);
  74. sa.build_sa();
  75. sa.build_height();
  76. sa.solve(len1);
  77.  
  78. return 0;
  79. }

poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403的更多相关文章

  1. poj2774 Long Long Message 后缀数组求最长公共子串

    题目链接:http://poj.org/problem?id=2774 这是一道很好的后缀数组的入门题目 题意:给你两个字符串,然后求这两个的字符串的最长连续的公共子串 一般用后缀数组解决的两个字符串 ...

  2. Long Long Message (poj2774 后缀数组求最长公共子串)

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 19206   Accepted: 79 ...

  3. poj2774 后缀数组 求最长公共子串

    Reference:IOI2009论文 http://www.cnblogs.com/ziyi--caolu/p/3192731.html #include "stdio.h" # ...

  4. POJ 2774 Long Long Message 后缀数组

    Long Long Message   Description The little cat is majoring in physics in the capital of Byterland. A ...

  5. POJ 2774 Long Long Message 后缀数组模板题

    题意 给定字符串A.B,求其最长公共子串 后缀数组模板题,求出height数组,判断sa[i]与sa[i-1]是否分属字符串A.B,统计答案即可. #include <cstdio> #i ...

  6. POJ 2774 Long Long Message (后缀数组+二分)

    题目大意:求两个字符串的最长公共子串长度 把两个串接在一起,中间放一个#,然后求出height 接下来还是老套路,二分出一个答案ans,然后去验证,如果有连续几个位置的h[i]>=ans,且存在 ...

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

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

  8. poj 2774 Long Long Message 后缀数组基础题

    Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 24756   Accepted: 10130 Case Time Limi ...

  9. POJ 2774 Long Long Message ——后缀数组

    [题目分析] 用height数组RMQ的性质去求最长的公共子串. 要求sa[i]和sa[i-1]必须在两个串中,然后取height的MAX. 利用中间的字符来连接两个字符串的思想很巧妙,记得最后还需要 ...

随机推荐

  1. JavaWeb基础之tomcat部署

    有些东西,看起来简单,做起来也简单,简单的你并不一定知道! 问题:如何将一个java project转变为 web project,并使其自动部署到tomcat? 1.先建立一个Java Projec ...

  2. python之字符串格式化(format)

    用法: 它通过{}和:来代替传统%方式 1.使用位置参数 要点:从以下例子可以看出位置参数不受顺序约束,且可以为{},只要format里有相对应的参数值即可,参数索引从0开,传入位置参数列表可用*列表 ...

  3. OpenCV学习 1:OpenCV安装与第一个图像显示程序

    原创作品,转载请注明出处 为了提升逼格,决定学下OpenCV,想想如果可以做人脸识别,定点降落,让飞机跟着自己飞..想想都有点小激动.这只是想的,能不能学会还不知道..哈..      1:先下载:h ...

  4. IE9下报错,错误: “JSON”未定义

    今天在公司运行的代码好好的,但是拿回家里以后就报错了 结果是IE9,没有设为兼容模式,唉,微软导出都是坑啊.

  5. Android updater-scripts(Edify Script)各函数详细说明(转)

    这是Android系统来运行updater-scripts的Edify语言的基本介绍. 大部分的Edify命名都是函数,当调用这些函数结束的时候,会返回数据给脚本.当然,你也可以使用这些函数的返回值来 ...

  6. iOS开发之主题皮肤

    iOS开发之主题皮肤 分类: [iOS]  最近在开发一款[公交应用],里面有个模块涉及到主题设置,这篇文章主要谈一下个人的做法. 大概的步骤如下: (1):整个应用依赖于一个主题管理器,主题管理器根 ...

  7. js完美继承代码示例

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 无废话ubuntu 13.4w文件共享配置

    目标:实现windows和linux混合组成的操作 系统中可以共享文件,并可以通过机器名互相访问 安装文件共享服务 0.更改本机主机名,修改 /etc/hostname文件和/etc/hosts文件中 ...

  9. android高仿微信拍照、多选、预览、删除(去除相片)相冊功能

    先声明授人与鱼不如授人与渔,仅仅能提供一个思路,当然须要源代码的同学能够私下有偿问我要源代码:QQ:508181017 工作了将近三年时间了,一直没正儿八经的研究系统自带的相冊和拍照,这回来个高仿微信 ...

  10. WPF 采用Border创建圆角

    通过设置可以创建圆角border的CornerRadius属性其边框呈现圆角样式 代码: <Border Height="50" Background="Red&q ...