点此看题面

大致题意: 求两个字符串中最长公共子串的长度。

关于后缀数组

关于\(Height\)数组的概念以及如何用后缀数组求\(Height\)数组详见这篇博客:后缀数组入门(二)——Height数组与LCP

大致思路

由于后缀数组是处理一个字符串的,因此我们第一步自然是将这两个字符串拼在一起,并在中间加一个不可能出现的字符,例如\(\%\)。

然后我们用后缀数组求出其\(Height\)数组。

注意一个性质,答案肯定是按字典序排名后相邻后缀的\(LCP\)值中的最大值

因此,我们只要枚举\(i\),判断后缀\(_{SA_i}\)与后缀\(_{SA_{i-1}}\)的起始字符是否在同一个字符串内,然后更新答案即可。

回顾\(Height\)数组定义就是\(Height_i=LCP(i,i-1)\)。

因此我们其实不用再额外去求相邻后缀的\(LCP\),直接调用\(Height\)数组即可。

具体实现详见代码。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #define N 100000
  4. #define Gmax(x,y) (x<(y)&&(x=(y)))
  5. using namespace std;
  6. int n,m;char s[(N<<1)+5];
  7. class Class_SuffixArray//后缀数组
  8. {
  9. private:
  10. int n,rk[(N<<1)+5],pos[(N<<1)+5],tot[(N<<1)+5];
  11. inline void RadixSort(int S)
  12. {
  13. register int i;
  14. for(i=0;i<=S;++i) tot[i]=0;
  15. for(i=1;i<=n;++i) ++tot[rk[i]];
  16. for(i=1;i<=S;++i) tot[i]+=tot[i-1];
  17. for(i=n;i;--i) SA[tot[rk[pos[i]]]--]=pos[i];
  18. }
  19. inline void GetSA(char *s)
  20. {
  21. register int i,k,cnt=0,Size=122;
  22. for(n=strlen(s),i=1;i<=n;++i) rk[pos[i]=i]=s[i-1];
  23. for(RadixSort(Size),k=1;cnt<n;k<<=1)
  24. {
  25. for(Size=cnt,cnt=0,i=1;i<=k;++i) pos[++cnt]=n-k+i;
  26. for(i=1;i<=n;++i) SA[i]>k&&(pos[++cnt]=SA[i]-k);
  27. for(RadixSort(Size),i=1;i<=n;++i) pos[i]=rk[i];
  28. for(rk[SA[1]]=cnt=1,i=2;i<=n;++i) rk[SA[i]]=(pos[SA[i-1]]^pos[SA[i]]||pos[SA[i-1]+k]^pos[SA[i]+k])?++cnt:cnt;
  29. }
  30. }
  31. inline void GetHeight(char *s)
  32. {
  33. register int i,j,k=0;
  34. for(i=1;i<=n;++i) rk[SA[i]]=i;
  35. for(i=1;i<=n;++i)
  36. {
  37. if(!(rk[i]^1)) continue;
  38. k&&--k,j=SA[rk[i]-1];
  39. while(i+k<=n&&j+k<=n&&!(s[i+k-1]^s[j+k-1])) ++k;
  40. Height[rk[i]]=k;
  41. }
  42. }
  43. public:
  44. int SA[(N<<1)+5],Height[(N<<1)+5];
  45. inline void Init(char *s) {GetSA(s),GetHeight(s);}
  46. }S;
  47. int main()
  48. {
  49. register int i,ans=0;
  50. scanf("%s",s),n=strlen(s),s[n]='%',scanf("%s",s+n+1),m=strlen(s+n+1);
  51. for(S.Init(s),i=1;i<=n+m;++i) if((S.SA[i]<n)^(S.SA[i-1]<n)) Gmax(ans,S.Height[i]);//如果相邻两个后缀的起始字符不在同一个字符串内,就更新答案
  52. return printf("%d",ans),0;
  53. }

【POJ2774】Long Long Message(后缀数组求Height数组)的更多相关文章

  1. Java后缀数组-求sa数组

    后缀数组的一些基本概念请自行百度,简单来说后缀数组就是一个字符串所有后缀大小排序后的一个集合,然后我们根据后缀数组的一些性质就可以实现各种需求. public class MySuffixArrayT ...

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

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

  3. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

  4. 【后缀数组之height数组】

    模板奉上 int rank[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { ; ;i<=n;i++) rank[sa[i]] ...

  5. POJ2774 Long Long Message [后缀数组]

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 29277   Accepted: 11 ...

  6. poj2774 Long Long Message(后缀数组or后缀自动机)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Long Long Message Time Limit: 4000MS   Me ...

  7. 求height数组

    procedure getheight; var i,po1,po2:longint; begin to len do begin ; po1:=i;po2:=sa[rank[i]-]; while ...

  8. poj 1743 男人八题之后缀数组求最长不可重叠最长重复子串

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14874   Accepted: 5118 De ...

  9. poj3261 Milk Patterns 后缀数组求可重叠的k次最长重复子串

    题目链接:http://poj.org/problem?id=3261 思路: 后缀数组的很好的一道入门题目 先利用模板求出sa数组和height数组 然后二分答案(即对于可能出现的重复长度进行二分) ...

随机推荐

  1. php路径问题

    ./ 是在当前目录开始寻找文件/ 是在下一级目录开始寻找文件 ../ 这个是在上一级目录开始寻找文件 $_SERVER['DOCUMENT_ROOT']获取站点根目录 __FILE__获取当前文件的完 ...

  2. QT的学习

    背景 最近正忙着做一个项目,由于之前对面向对象编程了解的非常少,所以导致项目的代码有很多不太清楚:看到代码的时候整个人是懵的.所以在国庆期间,结合着大神的博客看了一下面向对象编程,并学习了开发GUI应 ...

  3. windows下安装python包

    1.windows下成功安装好python后,在安装目录的Scripts目录下有easy_install和pip工具 2.如果没有安装pip,进入命令行,切换到python的安装目录下的Scripts ...

  4. 平衡树合集(Treap,Splay,替罪羊,FHQ Treap)

    今天翻了翻其他大佬的博客,发现自己有些...颓废... 有必要洗心革面,好好学习 序:正常的BST有可能退化,成为链,大大降低效率,所以有很多方法来保持左右size的平衡,本文将简单介绍Treap,S ...

  5. Codeforces Round #565 (Div. 3) B. Merge it!

    链接: https://codeforces.com/contest/1176/problem/B 题意: You are given an array a consisting of n integ ...

  6. mybatis批量处理sql

    转载大神 https://www.cnblogs.com/xujingyang/p/8301130.html

  7. sqlserver2008执行200M以上的大脚本文件,打开脚本总是报“未能完成操作,存储空间不足”

    用sqlcmd命令行工具. 1.win7下快捷键:win+R 2.输入cmd​,确定 3.输入命令:sqlcmd -S <数据库> -i C:\<数据文件>.sql 例:sql ...

  8. 在MFC对话框中快速集成三维控件

    在MFC的对话框中可以方便的集成AnyCAD三维控件(c++版本),遵循一下几步: 1.在对话框资源中增加一个Static控件,ID为IDC_STATIC_3D,并且把它的Notify属性设置为Tru ...

  9. 自动布局库--Masonry使用

    参考资料(戳这里): >  Masonry官网 >  Masonry介绍与使用实践(快速上手Autolayout) >  iOS 开发实践之 Auto Layout >  Ma ...

  10. Java语言程序设计(第三版)第二章课后习题答案(仅供参考)

    2.1   注意不同类型转换 import java.util.Scanner; public class Ch02 { public static void main(String[] args) ...