题目链接http://poj.org/problem?id=2217

题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续。

解题思路

后缀数组解法是这类问题的模板解法。

对于n个串的最长公共子串,这要把这些串连在一起,中间用"$"这类的特殊符号分隔一下。

先求后缀数组,再求最长公共前缀,取相邻两个且属于不同串的sa的最大LCP即可。

原理就是:这样把分属两个串的LCP都跑了一遍,也就是相当于把所有子串走了一遍,

只不过走这些子串是经过层层预处理过的。

下面提供一个使用的string模板,稍微稳定点。

  1. #include "cstring"
  2. #include "cstdio"
  3. #include "string"
  4. #include "iostream"
  5. using namespace std;
  6. #define maxn 30000
  7. struct Suffix
  8. {
  9. int r[maxn];
  10. int sa[maxn],rank[maxn],height[maxn];
  11. int t[maxn],t2[maxn],c[maxn],n,m;
  12. void init(string s)
  13. {
  14. n=s.size();
  15. for(int i=;i<n;i++) r[i]=(int)s[i];
  16. m=;
  17. }
  18. int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];}
  19. void build()
  20. {
  21. int i,k,p,*x=t,*y=t2;
  22. r[n++]=;
  23. for (i=; i<m; i++) c[i]=;
  24. for (i=; i<n; i++) c[x[i]=r[i]]++;
  25. for (i=; i<m; i++) c[i]+=c[i-];
  26. for (i=n-; i>=; i--) sa[--c[x[i]]]=i;
  27. for (k=,p=; k<n; k*=,m=p)
  28. {
  29. for (p=,i=n-k; i<n; i++) y[p++]=i;
  30. for (i=; i<n; i++) if (sa[i]>=k) y[p++]=sa[i]-k;
  31. for (i=; i<m; i++) c[i]=;
  32. for (i=; i<n; i++) c[x[y[i]]]++;
  33. for (i=; i<m; i++) c[i]+=c[i-];
  34. for (i=n-; i>=; i--) sa[--c[x[y[i]]]]=y[i];
  35. swap(x,y);
  36. p=;
  37. x[sa[]]=;
  38. for (i=; i<n; i++) x[sa[i]]=cmp(y,sa[i-],sa[i],k)?p-:p++;
  39. }
  40. n--;
  41. }
  42. void LCP()
  43. {
  44. int i,j,k=;
  45. for (i=; i<=n; i++) rank[sa[i]]=i;
  46. for (i=; i<n; i++)
  47. {
  48. if (k) k--;
  49. j=sa[rank[i]-];
  50. while (r[i+k]==r[j+k]) k++;
  51. height[rank[i]]=k;
  52. }
  53. }
  54. int LCS(string s1,string s2)
  55. {
  56. int len=s1.size();
  57. s1=s1+"$"+s2;
  58. init(s1);
  59. build();
  60. LCP();
  61. int ans=;
  62. for(int i=;i<=n;i++)
  63. if((sa[i-]<len)!=(sa[i]<len)) ans=max(ans,height[i]);
  64. return ans;
  65. }
  66. };
  67.  
  68. int main()
  69. {
  70. //freopen("in.txt","r",stdin);
  71. ios::sync_with_stdio(false);
  72. int T;
  73. string s,t;
  74. cin>>T;getline(cin,s);
  75. while(T--)
  76. {
  77. getline(cin,s);
  78. getline(cin,t);
  79. Suffix a;
  80. cout<<"Nejdelsi spolecny retezec ma delku "<<a.LCS(s,t)<<"."<<endl;
  81. }
  82. }
13557348 neopenx 2217 Accepted 1060K 32MS C++ 2109B 2014-10-23 10:35:07

POJ 2217 (后缀数组+最长公共子串)的更多相关文章

  1. [poj 2274]后缀数组+最长公共子串

    题目链接:http://poj.org/problem?id=2774 后缀数组真的太强大了,原本dp是O(nm)的复杂度,在这里只需要O(n+m). 做法:将两个串中间夹一个未出现过的字符接起来,然 ...

  2. POJ-2774-Long Long Message(后缀数组-最长公共子串)

    题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...

  3. POJ3294 Life Forms —— 后缀数组 最长公共子串

    题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total ...

  4. POJ 2774 (后缀数组 最长公共字串) Long Long Message

    用一个特殊字符将两个字符串连接起来,然后找最大的height,而且要求这两个相邻的后缀的第一个字符不能在同一个字符串中. #include <cstdio> #include <cs ...

  5. POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]

    题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submiss ...

  6. poj 1458 Common Subsequence_最长公共子串

    题意:略 求最长公共子串 #include<iostream> #include<cstdio> #include<string> using namespace ...

  7. POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数

    题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K ...

  8. CSU1632Repeated Substrings(后缀数组/最长公共前缀)

    题意就是求一个字符串的重复出现(出现次数>=2)的不同子串的个数. 标准解法是后缀数组.最长公共前缀的应用,对于样例aabaab,先将所有后缀排序: aab 3    aabaab 1    a ...

  9. POJ3450 Corporate Identity —— 后缀数组 最长公共子序列

    题目链接:https://vjudge.net/problem/POJ-3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536 ...

随机推荐

  1. OpenGL顶点缓冲区对象(VBO)

    转载 http://blog.csdn.net/dreamcs/article/details/7702701 创建VBO        GL_ARB_vertex_buffer_object 扩展可 ...

  2. 异常详细信息: System.Data.SqlClient.SqlException:用户 'IIS APPPOOL\DefaultAppPool' 登录失败解决办法

    1.安全性---登录名---新建登录名 2.常规----搜索 3.添加SERVICE用户-- 4.服务器角色---勾上sysadmin: IIS中: 应用程序池---对应的程序池上右键---高级设置 ...

  3. Linux netstat详解

    做计算机管理员,我们都必要了解一下netstat这个命令,它是一个查看网络连接状态的工具,在windows下也默认有这个工具.Netstat命令详解 netstat命令怎样使用 如何关闭TIME_WA ...

  4. Java 7 的7个新特性

    1.对集合类的语言支持:(??) 2.自动资源管理: 3.改进的通用实例创建类型推断:(??) 4.数字字面量下划线支持:(√) 5.switch中使用string:(√) 6.二进制字面量:(√) ...

  5. 【转】maven命令背后是如何工作的

    转载自:http://yinny.iteye.com/blog/1883488 Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),它有三套相互独立的生命周期,请注意 ...

  6. codeforces B. Vasya and Public Transport 解题报告

    题目链接:http://codeforces.com/problemset/problem/355/B 题目意思:给出四种票种,c1: 某一部bus或者trolley的单程票(暗含只可以乘坐一次):c ...

  7. HDU 1023 Traning Problem (2) 高精度卡特兰数

    Train Problem II Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Sub ...

  8. Markdown 语法速查表

      Markdown 语法速查表 1 标题与文字格式 标题 # 这是 H1 <一级标题> ## 这是 H2 <二级标题> ###### 这是 H6 <六级标题> 文 ...

  9. ShareSDK集成微信、QQ、微博分享

    1.前言 为什么要使用第三方的作为集成分享的工具呢?而不去用官方的呢?有什么区别么? 一个字"快",如果你使用官方的得一个个集成他们的SDK,相信这是一个痛苦的过程. 2.准备需要 ...

  10. 一个非常简单的返回局部字符数组的C语言程序, 请问其输出结果?

    以下是该无聊的程序: #include <stdio.h> #include <string.h> char* get_str() {     int x[10];     c ...