这题要求两个串中的最长相同子串的长度。高度数组可以求一个串中的最长相同子串的长度。所以想到把两个串连起来,但是这样又会产生一些新的串(第一个串的结尾和第二个串的开头组成的)于是在两个串中间放一个'\0'分隔,正好'\0'是字符里最小的,不会对第一个串的排序产生影响。

Accepted 1403 62MS 5344K 2117 B G++
  1. #include "bits/stdc++.h"
  2. using namespace std;
  3. const int MAXN = 2e5 + ;
  4. char s[MAXN];
  5. int x[MAXN], y[MAXN], cnt[MAXN];
  6. int sa[MAXN], rk[MAXN], height[MAXN];
  7. int a, b, ans;
  8. void getSa(int n, int m) {
  9. for (int i = ; i <= m; i++) {
  10. cnt[i] = ;
  11. }
  12. for (int i = ; i <= n; i++) {
  13. cnt[x[i] = s[i]]++;
  14. }
  15. for (int i = ; i <= m; i++) {
  16. cnt[i] += cnt[i - ];
  17. }
  18. for (int i = n; i; i--) {
  19. sa[cnt[x[i]]--] = i;
  20. }
  21. int num = ;
  22. for (int j = ; num < n; j <<= , m = num) {
  23. num = ;
  24. for (int i = n - j + ; i <= n; i++) {
  25. y[++num] = i;
  26. }
  27. for (int i = ; i <= n; i++) {
  28. if (sa[i] > j) {
  29. y[++num] = sa[i] - j;
  30. }
  31. }
  32. for (int i = ; i <= m; i++) {
  33. cnt[i] = ;
  34. }
  35. for (int i = ; i <= n; i++) {
  36. cnt[x[i]]++;
  37. }
  38. for (int i = ; i <= m; i++) {
  39. cnt[i] += cnt[i - ];
  40. }
  41. for (int i = n; i; i--) {
  42. sa[cnt[x[y[i]]]--] = y[i];
  43. }
  44. swap(x, y);
  45. num = ;
  46. x[sa[]] = ;
  47. for (int i = ; i <= n; i++) {
  48. if (y[sa[i]] != y[sa[i - ]] || y[sa[i] + j] != y[sa[i - ] + j]) {
  49. x[sa[i]] = ++num;
  50. } else {
  51. x[sa[i]] = num;
  52. }
  53. }
  54. }
  55. }
  56. void getHeight(int n) {
  57. for (int i = ; i <= n; i++) {
  58. rk[sa[i]] = i;
  59. }
  60. int k = ;
  61. for (int i = ; i <= n; i++) {
  62. int j = sa[rk[i] - ];
  63. k = k ? k - : k;
  64. while (s[i + k] == s[j + k]) {
  65. k++;
  66. }
  67. // height[rk[i]] = k;
  68.  
  69. // 如果i和j位于前后两个不同的串,更新ans
  70. if ((i <= a + ) ^ (j <= a + )) {
  71. ans = max(ans, k);
  72. }
  73. }
  74. }
  75. int main() {
  76. while (~scanf("%s", s + )) {
  77. a = strlen(s + );
  78. // 把第二个字符串直接输入到第一个字符串的'\0'后面,例如输入两个"abc"就是"\0abc\0abc\0"
  79. scanf("%s", s + a + );
  80. b = strlen(s + a + );
  81. // n表示第一个串的长度,m表示第二个串的长度,加上中间的'\0'要求后缀数组的部分长度为n + m + 1,也就是"abc\0abc"这部分
  82. getSa(a + b + , );
  83. ans = ;
  84. // 在求高度数组的时候为避免第二个串后面的'\0'和第一个串后面的'\0'对结果造成影响。"abc\0" == "abc\0" 将第二个串后面的'\0'改成字符串中不可能出现的字符
  85. s[a + b + ] = '';
  86. getHeight(a + b + );
  87. printf("%d\n", ans);
  88. }
  89. return ;
  90. }

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. 【HDOJ】1403 Longest Common Substring

    后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXM 28 ...

随机推荐

  1. h5-携程页面小案例-伸缩盒子

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

  2. Python使用+和*操作符 连接2个列表和列表的复制

    + 操作符通常连接两个列表可以使用 +进行连接得到一个新列表 *操作符择可以用于一个列表和一个整数,实现列表的复制.

  3. 干货 | 玩转云文件存储——利用CFS实现web应用的共享访问

    京东云文件服务(Cloud File Service,以下简称:CFS)是一种高可靠.可扩展.可共享访问的全托管分布式文件系统.它可在不中断应用服务的情况下,根据您对文件系统的使用,按需扩展或缩减,并 ...

  4. 干货 | CDN搭配OSS最佳实践 ——搭建动静态分离的应用架构

    一.传统架构及痛点 传统的网站产品应用架构,所有资源部署在应用服务器本地存储或挂载的数据存储区,对于动静态资源不作分离, 产品架构如下图所示: 该架构存在诸多问题: ● 系统性能会随着系统访问量的增长 ...

  5. py02_02:pyc的解释

    1. Python是一门解释型语言吗? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在.如果是解释型语言 ...

  6. JavaSE--数字签名之校验签名

    参考:http://blog.csdn.net/dotuian/article/details/51722300 关于keystore的简单介绍 Keytool是一个Java数据证书的管理工具 ,Ke ...

  7. jenkins pipeline 之 deploy k8s 环境并发送邮件通知

    项目中有更新代码之后触发jenkins任务,部署好之后并发送邮件给发开人员 #!/usr/bin/env groovy Date date = new Date()def time = date.fo ...

  8. 扯下Python的super()

    注: Python 2.7.x 环境下 今晚搜东西无意中看到这篇Understanding Python super() with __init__() methods. 其实这篇老早就看过了, 不过 ...

  9. 11)PHP,单选框和复选框的post提交方式处理

    就是一个表单中会有input的checkbox形式,那么怎么处理,就有了问题,一般采用二维数组来处理 代码展示: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  10. Springboot中RestTemplate -- 用更优雅的方式发HTTP请求

    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率. 我之前的HTTP开发是用ap ...