hihoCoder 1415 后缀数组三·重复旋律3(最长公共子串)
来源:互联网 发布:linux 时间格式 编辑:程序博客网 时间:2024/05/16 14:13
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为长度为 N 的数构成的数列。小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分。
旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过。小Hi想知道两部作品的共同旋律最长是多少?
解题方法提示
输入
共两行。一行一个仅包含小写字母的字符串。字符串长度不超过 100000。
输出
一行一个整数,表示答案。
abcdefgabacabca
样例输出
3
思路:把两个串连接成一个串,中间用'#'分开,然后从头到尾枚举一遍height值,如果前面在一个串,后面再另一个
串,那么这个height值是可以计算的,找出可计算的最大值即可。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 3e5+5;int t1[maxn], t2[maxn], c[maxn];int ra[maxn], height[maxn];int sa[maxn];char str[maxn], str1[maxn], str2[maxn];bool cmp(int *r, int a, int b, int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(char str[], int sa[], int ra[], int height[], int n, int m){ n++; 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]=str[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]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++; if(p >= n) break; m = p; } int k = 0; n--; for(i = 0; i <= n; i++) ra[sa[i]] = i; for(i = 0; i < n; i++) { if(k) k--; j = sa[ra[i]-1]; while(str[i+k]==str[j+k]) k++; height[ra[i]] = k; }}int solve(int n, int len){ int ans = 0; for(int i = 2; i <= n; i++) { if(sa[i-1] < len && sa[i] > len || sa[i] < len && sa[i-1] > len) ans = max(ans, height[i]); } return ans;}int main(void){ while(~scanf(" %s %s", str1, str2)) { int len1 = strlen(str1); int len2 = strlen(str2); for(int i = 0; i < len1; i++) str[i] = str1[i]; str[len1] = '#'; for(int i = 0; i < len2; i++) str[len1+i+1] = str2[i]; int len = len1+len2+1; str[len] = 0; da(str, sa, ra, height, len, 127); int ans = solve(len, len1); printf("%d\n", ans); } return 0;}
阅读全文
1 0
- hihoCoder 1415 后缀数组三·重复旋律3(最长公共子串)
- Hiho 122 后缀数组三·重复旋律3(多个串的最长公共重复子串)
- hihoCoder #1415 : 后缀数组三·重复旋律3
- hihoCoder 1403后缀数组一·重复旋律(最长可重叠重复子串问题)
- hihoCoder 1407 后缀数组二·重复旋律2 && POJ 1743 Musical Theme(最长不可重叠重复子串问题)
- hihoCoder 1419 后缀数组四·重复旋律4(重复次数最多的连续子串)
- 后缀数组三·重复旋律3
- Hiho 121 后缀数组二·重复旋律2(最长不可重叠重复子串问题)
- 重复旋律 后缀数组 板子 最长可重叠重复子串问题
- hihoCoder #1403 : 后缀数组一·重复旋律
- hihoCoder #1407 : 后缀数组二·重复旋律2
- hihoCoder 1403 后缀数组 重复旋律
- 后缀数组 (hihocoder重复旋律系列)
- hiho一下 第122周 后缀数组三·重复旋律3
- 最长公共子串--后缀数组实现
- HDU1403(后缀数组--最长公共子串)
- 最长公共子串(后缀数组)
- 最长公共子串(后缀数组)
- 元素同址操作结构
- Section 2.1 castle
- Poj 1741 Tree 点分治 解题报告
- HDOJ 1026 Ignatius and the Princess I (BFS优先队列超时 TLE)
- 【loli的胡策】NOIP训练7.17(模拟+乱搞二进制+乱搞BFS)
- hihoCoder 1415 后缀数组三·重复旋律3(最长公共子串)
- MySQLのカラム定義の問題だった
- 【Deep Learning】循环神经网络(RNN)推导和实现
- uikit——Auto Layout——Top&Bottom Layout Guide
- Java中extends和implements区别
- 概念1
- Struts2开发实例-http status 500
- Trading Terms
- 深入解析JavaScript闭包:从作用域与作用域链s