题目链接:点击查看

题目大意:给出两个字符串,求出其最长的公共子串

题目分析:后缀数组水题,直接用一个不同的符号拼接一下两个字符串,然后跑出height数组和sa数组,再遍历一遍取最大值就是答案了,需要注意的一个地方就是,若想让height对答案作出贡献,必须满足sa数组表示的两个数在不同符号的两侧才行

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e5+100;char s1[N],s2[N];int sa[N]; //SA数组,表示将S的n个后缀从小到大排序后把排好序的
//的后缀的开头位置顺次放入SA中
int t1[N],t2[N],c[N];int rk[N],height[N],n;int s[N];void build_sa(int s[],int n,int m)//n为添加0后的总长
{int i,j,p,*x=t1,*y=t2;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[i]=s[i]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for(j=1;j<=n;j<<=1) {p=0;for(i=n-j;i<n;i++) y[p++]=i;for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[y[i]]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1,x[sa[0]]=0;for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;if(p>=n) break;m=p;}
}void get_height(int s[],int n)//n为添加0后的总长
{int i,j,k=0;for(i=0;i<=n;i++)rk[sa[i]]=i;for(i=0;i<n;i++) {if(k) k--;j=sa[rk[i]-1];while(s[i+k]==s[j+k]) k++;height[rk[i]]=k;}
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);scanf("%s%s",s1,s2);for(int i=0;s1[i];i++)s[i]=s1[i]-'a'+1;int mark=strlen(s1);s[mark]=30;for(int i=0;s2[i];i++)s[i+mark+1]=s2[i]-'a'+1;n=strlen(s1)+strlen(s2)+1;s[n]=0;build_sa(s,n+1,31);get_height(s,n);int ans=0;for(int i=2;i<=n-1;i++)if(sa[i-1]<mark&&sa[i]>mark||sa[i-1]>mark&&sa[i]<mark)ans=max(ans,height[i]);printf("%d\n",ans);return 0;
}

POJ - 2774 Long Long Message(后缀数组)相关推荐

  1. POJ 2774 Long Long Message SP1811 LCS - Longest Common Substring 题解

    POJ:题目传送门 洛谷:题目传送门 题目大意: 求两个字符串的最长公共子串长度. 题解 后缀数组入门题,将两个字符串接在一起,中间用一个字符集以外的字符隔开,然后求出 h e i g h t hei ...

  2. POJ - 3261 Milk Patterns(二分+后缀数组)

    题目链接:点击查看 题目大意:给出一个字符串,以及一个k,现在求出现次数大于等于k次的最大可重叠子串的长度 题目分析:可以说是后缀数组的模板题目了吧..直接跑出height数组,因为height数组代 ...

  3. POJ - 3450 Corporate Identity(二分+后缀数组)

    题目链接:点击查看 题目大意:给出n个字符串,求出n个字符串中最长的公共子串,如果没有,输出IDENTITY LOST 题目分析:可以直接用二分+后缀数组来做,先将n个字符串连接起来,中间用一个不同的 ...

  4. POJ - 1743 Musical Theme(二分+后缀数组+差分数组)

    题目链接:点击查看 题目大意:给出n个连续的数字组成的序列,现在要求出其中两个不重叠的字序列,满足两个子序列"相似",相似的定义是两个子序列当且仅当长度相等并且每一位的数字差都相等 ...

  5. POJ.2774.Long Long Message/SPOJ.1811.LCS(后缀数组 倍增)

    题目链接 POJ2774 SPOJ1811 LCS - Longest Common Substring 比后缀自动机慢好多(废话→_→). \(Description\) 求两个字符串最长公共子串 ...

  6. POJ - 3693 Maximum repetition substring(后缀数组+RMQ)

    题目链接:点击查看 题目大意:给出一个字符串,求出字符串中 重复次数最多的连续重复子串 ,如果有多个答案,输出字典序最小的 题目分析:又是一个模板题,这里放一个大佬的博客,讲的很清楚: https:/ ...

  7. POJ - 3294 Life Forms(二分+后缀数组)

    题目链接:点击查看 题目大意:给出n个字符串,求出至少在n/2个字符串中出现的最长的公共子串,如果没有,输出"?" 题目分析:和poj3450几乎一样的题目,只不过最长公共子串出现 ...

  8. POJ 2217:Secretary(后缀数组)

    题目大意:求两个字符串的公共子串. 分析: 模板题,将两个字符串接起来用不会出现的字符分割,然后求分属两个字符串的相邻后缀lcp的最大值即可. 代码: program work; typearr=ar ...

  9. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

最新文章

  1. Scrum卡片层次图
  2. Win7 配置Android开发环境
  3. flyway使用简介
  4. JavaScript——易班优课YOOC课群在线测试自动答题解决方案(七)随机答案
  5. boost::local_time模块实现航班飞行时间的测试程序
  6. java输出日志_java代码中如何正确使用loggger日志输出
  7. 【读书笔记】并发编程需要注意的几个典型问题
  8. Swagger工作笔记001---Swagger2的使用
  9. xp 挂linux上网,XP系统挂载Linux NFS共享
  10. yaws mysql_MySQL入门之C语言操作MySQL
  11. jquery 使用文档
  12. 百度AI之身份证识别
  13. TDD测试驱动开发案例【水货】
  14. 神经网络 II:神经元模型
  15. html当前页面的脚本发生错误,如何解决“当前页面脚本发生错误”的问题
  16. 【扫描线】火星探险-线段树
  17. 免费壁纸背景高清图片素材网站
  18. 本科生通信工程毕业何去何从
  19. ISO8583报文128个域说明
  20. 正圆锥体空间方程_电路原理中三相缺相保护器是如何工作的,正负序与它有什么关系...

热门文章

  1. 登录方式1:MySQL自带客户端
  2. 关系型数据库(RDBMS)实质
  3. MySQL高级 - 常用工具 - mysqlbinlog与mysqldump
  4. MySQL高级 - 常用工具 - mysql
  5. Atomic Integer 原理分析-getAndAddInt
  6. IOC 容器中那些鲜为人知的细节
  7. File类判断和获取功能
  8. 悔不当初:回顾进化之路
  9. 字符输出流的续写和换行
  10. spring中的aop术语和细节