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

Accepted 1403 62MS 5344K 2117 B G++
#include "bits/stdc++.h"
using namespace std;
const int MAXN = 2e5 + ;
char s[MAXN];
int x[MAXN], y[MAXN], cnt[MAXN];
int sa[MAXN], rk[MAXN], height[MAXN];
int a, b, ans;
void getSa(int n, int m) {
for (int i = ; i <= m; i++) {
cnt[i] = ;
}
for (int i = ; i <= n; i++) {
cnt[x[i] = s[i]]++;
}
for (int i = ; i <= m; i++) {
cnt[i] += cnt[i - ];
}
for (int i = n; i; i--) {
sa[cnt[x[i]]--] = i;
}
int num = ;
for (int j = ; num < n; j <<= , m = num) {
num = ;
for (int i = n - j + ; i <= n; i++) {
y[++num] = i;
}
for (int i = ; i <= n; i++) {
if (sa[i] > j) {
y[++num] = sa[i] - j;
}
}
for (int i = ; i <= m; i++) {
cnt[i] = ;
}
for (int i = ; i <= n; i++) {
cnt[x[i]]++;
}
for (int i = ; i <= m; i++) {
cnt[i] += cnt[i - ];
}
for (int i = n; i; i--) {
sa[cnt[x[y[i]]]--] = y[i];
}
swap(x, y);
num = ;
x[sa[]] = ;
for (int i = ; i <= n; i++) {
if (y[sa[i]] != y[sa[i - ]] || y[sa[i] + j] != y[sa[i - ] + j]) {
x[sa[i]] = ++num;
} else {
x[sa[i]] = num;
}
}
}
}
void getHeight(int n) {
for (int i = ; i <= n; i++) {
rk[sa[i]] = i;
}
int k = ;
for (int i = ; i <= n; i++) {
int j = sa[rk[i] - ];
k = k ? k - : k;
while (s[i + k] == s[j + k]) {
k++;
}
// height[rk[i]] = k; // 如果i和j位于前后两个不同的串,更新ans
if ((i <= a + ) ^ (j <= a + )) {
ans = max(ans, k);
}
}
}
int main() {
while (~scanf("%s", s + )) {
a = strlen(s + );
// 把第二个字符串直接输入到第一个字符串的'\0'后面,例如输入两个"abc"就是"\0abc\0abc\0"
scanf("%s", s + a + );
b = strlen(s + a + );
// n表示第一个串的长度,m表示第二个串的长度,加上中间的'\0'要求后缀数组的部分长度为n + m + 1,也就是"abc\0abc"这部分
getSa(a + b + , );
ans = ;
// 在求高度数组的时候为避免第二个串后面的'\0'和第一个串后面的'\0'对结果造成影响。"abc\0" == "abc\0" 将第二个串后面的'\0'改成字符串中不可能出现的字符
s[a + b + ] = '';
getHeight(a + b + );
printf("%d\n", ans);
}
return ;
}

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. str_replace用法

    语法 str_replace(find,replace,string,count) 参数 描述 find 必需.规定要查找的值. replace 必需.规定替换 find 中的值的值. string ...

  2. 题解 P1447 【[NOI2010]能量采集】

    题目 这题不要用莫比乌斯反演,用欧拉反演更快 [分析] 设点 \((x,y)\) 的能量损失为 \(f(x,y)\) 则 \(\displaystyle Ans=\sum_{i=1}^n\sum_{j ...

  3. java依赖包问题排查

    使用算法 breeze.optimize.LBFGSB,出现如下问题: 看到github上一个issue的解决方法是使用最新版本的 org.scalanlp:breeze_2.11:1.0-RC2, ...

  4. nfs 支持ipv6

    mount 一个ipv6 nfs 项目在docker里mount 一个nfs来读写,而现在需要支持ipv6,所以先写了各小demo,最后成功mount,这里记录一下 #include <sys/ ...

  5. ccf201403-3 记录一个神tmwa了的代码 莫非我没看懂题。。。

    #include <string.h> #include<cstdio> #include<stdio.h> #include <iostream> # ...

  6. 【hdu6613】Squrirrel 树形DP

    题意:给一个带权树,求把一条边的权值变成0,再选一个点做根,最大深度最小是多少. \(\sum n \le 10^6\) key:树形DP 题里有边权小于等于200,然而并没有什么用. 首先做出 \( ...

  7. Notification通知在OPPO手机上不弹出提示?

    oppo默认应用 不允许通知. 解决步骤:设置 通知与状态栏 通知管理 NotificationTest 允许通知

  8. Multiple alleles|an intuitive argument|

    I.5 Multiple alleles. 由两个等位基因拓展到多个等位基因,可以得到更多种二倍体基因型: 所以单个等位基因的概率(用i代指某个基因,pi*是该基因的频率)是(以计数的方法表示) 所以 ...

  9. AI大火之下智能手机行业能适应这一风口吗?

    今年智能手机行业的变化,实在是让人摸不到头脑.一方面是智能手机厂商依然在拿出各种具有噱头的产品,仿佛整个市场还依然热火朝天.但在另一方面,智能手机出货量却出现大幅下滑.据中国信息通信研究院发布的数据显 ...

  10. 《VSTO开发中级教程》刘永富 著 清华大学出版社 在线购买

    现在可以和作者 刘永富 通过“二手书直卖”这个APP直接买书. 二手书直卖 的下载方法: 方法一:加QQ群61840693,群共享中搜索“二手书直卖”,下载后打开即可. 方法二:从本帖下载:二手书直卖 ...